Rails many to one association - Help showing many in one view - ruby-on-rails-3

These are my models:
class Bedommelse < ActiveRecord::Base belongs_to :virksomhed_primary,
:class_name => 'Virksomhed',
:foreign_key => 'virksomhed_id' belongs_to :virksomheds,
:foreign_key => "virksomhed_id"
end
class Bedommelse < ActiveRecord::Base belongs_to :virksomheds,
:foreign_key => "virksomhed_id" belongs_to :freelances,
:foreign_key => "freelance_id"
end
I am trying to display the name of the virksomhed_id not the id itself in the One View (Bedommelse view)
I can show the column virksomhed_id:
<% #bedommelses.each do |bedommelse| %>
<p><%= bedommelse.virksomhed_id</p>
<% end %>
How do I show the name of the virksomhed?
I have tried this but it didn't work.
<% #bedommelses.each do |bedommelse| %>
<p><%= bedommelse.virksomhed.navn </p>
<% end %>

I have found my mistake
I did a fail in the models:
It should be:
belongs_to :virksomhed
not
belongs_to :virksomheds
And the view should be:
<%= #bedommelse.virksomhed.navn %>

Related

Rails 3 my first nested form doesnt work - Can't mass-assign protected attributes

I'm creating my first nested form in Rails 3.2.13. User is registering and he fill email, password and address information and company information.. but the error is showing while user click on submit. Error is at the bottom.
Im not sure about this line: attr_accessible :address_attributes, :company_attributes
which i read it could help but it doesnt and i have addresses in the view but address in the model because of one-to-one relationship but if i have <%= f.fields_for :**address** do |builder| %> the form doesnt show up.
Please what i have to do ? :-)
The post sends then
"companies"=>{"name"=>"Companyname"
User model
class User < ActiveRecord::Base
attr_accessible ...
has_many :orders
belongs_to :address
belongs_to :company
accepts_nested_attributes_for :address, :company
attr_accessible :address_attributes, :company_attributes
Company model
class Company < ActiveRecord::Base
attr_accessible ...
has_many :users
validates_presence_of ...
end
Address model
class Address < ActiveRecord::Base
attr_accessible ...
has_many :orders, :foreign_key => 'payment_address_id'
has_many :orders, :foreign_key => 'delivery_address_id'
has_many :users
validates_presence_of ...
end
new.html.erb (creating new user)
<%= form_for #user do |f| %>
...
<%= f.fields_for :addresses do |builder| %>
...
<% end %>
<%= f.fields_for :companies do |builder| %>
...
<% end %>
<%= f.submit %>
<% end %>
error while i click on submit
Can't mass-assign protected attributes: addresses, companies
EDIT:
First mistake: i changed in Class User
belongs_to :address
belongs_to :company
on
has_one :address
has_one :company
and in Address and Company model i edit
has_many :users
on
belongs_to :user
but nested forms doesnt show up in the view.. i tried edit Users Controller by adding .build method
def new
#user = User.new
#user.company.build
#user.address.build
end
but im getting new error
undefined method `build' for nil:NilClass
please what i have to do now ?
I had a case like this a day ago, and that's what I used.
class User
attr_accessible :name, :email, :company_attributes, :address_attributes
has_one :company
accepts_nested_attributes_for :company
end
and EmailSetting:
class Company
belongs_to :user
end
after this I can run in console:
User.new.build_company
as for form:
<%= form_for #user do |f| %>
<%= f.fields_for :company do |builder| %>
<%= f.text_field :name %>
<% end %>
<% end %>
in controller you just initialize the #user variable, no need to do #user.company.build or #user.address.build

jQuery TokenInput plugin with deep nested_attributes pre-populating tokens on edit

I have the following structure working on my application.
class Foo < ActiveRecord::Base
has_many :examples, :dependent => :destroy
accepts_nested_attributes_for :examples
end
class Example < ActiveRecord::Base
belongs_to :foo
has_many :codes, :dependent => :destroy
accepts_nested_attributes_for :codes, :reject_if => lambda { |a| a[:code].blank? }
end
class Code < ActiveRecord::Base
belongs_to :example
has_many :code_kinds
has_many :kinds, :through => :code_kinds
attr_reader :kind_tokens
def kind_tokens=(ids)
self.kind_ids = ids.split(",")
end
end
class CodeKind < ActiveRecord::Base
belongs_to :code
belongs_to :kind
end
class Kind < ActiveRecord::Base
has_many :code_kinds
has_many :codes, :through => :code_kinds
end
And it's working perfectly for the form with fields_for on create and save.
I'm using kind_tokens as described on RailsCast #258 Token Fields
But on the edit form everything displays perfectly now I should be pre-populating the data in a data-pre attribute on the kind_tokens field inside the nested attributes for code in examples.
The RailsCast say:
<%= f.text_field :author_tokens, "data-pre" => #book.authors.map(&:attributes).to_json %>
But I can't do #foo.examples.codes.kinds.map... because the relation with Foo and examples returns a collection, the same situation with codes.
I'm just using:
<%= f.fields_for :codes do |codes_form| %>
That's inside of
<%= f.fields_for :examples do |examples_form| %>
Now how can I pre-populate the kind for code if I don't have any loop, and everything's done by nested_attributes and fields_for ?
Solved
Everytime you use a
<%= f.fields_for ...
Rails automatically makes a loop so you can have some kind of counter there like:
<%
#ctrEx = 0
#ctrCd = 0
%>
<%= form_for #foo ...
<%= f.fields_for :examples do |examples_form| %>
...
<%= examples_form.fields_for :codes do |codes_form| %>
...
<%= codes_form.text_field :kind_tokens, :class => "tag_matcher", "data-pre" => #foo.examples[#ctrEx].codes[#ctrCd].kinds.map(&:attributes).to_json %>
...
<%#ctrCd +=1%>
<%end%>
...
<%
#ctrEx += 1
#ctrCd = 0
%>
<%end%>
<%end%>
Now you can use your counters in the data-pre like this:
#foo.examples[#ctrEx].codes[#ctrCd].kinds.map(&:attributes).to_json
That's the way i figured it out, but there must be another way.

saving record to join table Has_many :through

I am new to Rails 3 and having trouble with saving records in the Join table. I have been looking around and trying different examples found on this website and from the documentation or books, but I don't understand why I can't get it to work. I am trying to create Authorization by creating Roles and associate them to users. So far I have been trying to assign roles from the update action in the Users controller without prevail.
I have 3 models: the User.rb, role.rb, and assignment.rb (the join table)
class User < ActiveRecord::Base
has_many :assignments, :dependent => :destroy
has_many :roles, :through => :assignments, :foreign_key => :role_id
accepts_nested_attributes_for :roles
attr_accessor :password, :role_ids
attr_accessible :first_name, :last_name, :email, :password, :password_confirmation, :status, :description, :username, :roles_attributes
...
end
class Role < ActiveRecord::Base
has_many :assignments
has_many :users, :through => :assignments, :foreign_key => :user_id
accepts_nested_attributes_for :users
attr_accessible :name
end
class Assignment < ActiveRecord::Base
belongs_to :user
belongs_to :role
accepts_nested_attributes_for :roles
end
The Users controller in the update action I have the following
class UsersController < ApplicationController
...
def update
#user = User.find(params[:id])
if #user.update_attributes(params[:user])
#user.roles.build
flash[:success] = "Profile updated"
redirect_to #user
else
#title = "Edit" + " " + #user.username
render 'edit'
end
end
...
end
and in the 'edit' view page I intend to have checkboxes to update the User record with an associated role:
EDIT: Changed the "check_box" with "check_box_tag" ... the check boxes appear properly, but the values are not saved.
<%= form_for(#user) do |f| %>
...
<div class="field">
<%= f.label :roles %><br />
<%= f.fields_for :role_ids do |r| %>
<% #roles.each do |role| %>
<%= check_box_tag "user[roles][]", role.id, #user.roles.include?(role.id) %>
<%= role.name %>
<% end %>
<%= hidden_field_tag "user[roles][]", "" %>
<% end %>
</div>
<% end %>
With this code I even get an error where 'Roles' have no association.
EDIT: this was corrected with the accepts_nested_attributes_for :role. Thanks!
No association found for name `roles'. Has it been defined yet?
I am really confused where I am doing something wrong. Your help would be much appreciated.
Aurelien
You have to use the same name with "accepts_nested_attributes_for" as you used defining the association:
class Assignment < ActiveRecord::Base
belongs_to :user
belongs_to :role
accepts_nested_attributes_for :role
end
Finally solved the problems and thought I could share.
The models associations but I did change the attr_accessible:
class User < ActiveRecord::Base
has_many :assignments, :dependent => :destroy
has_many :roles, :through => :assignments, :foreign_key => :role_id
accepts_nested_attributes_for :roles
attr_accessor :password
attr_accessible ..., :roles_ids
...
end
In the User controller for the edit and update action.
def edit
#title = "Edit" + " " + #user.username
#roles = Role.find(:all)
#user.assignments.build
end
def update
#user = User.find(params[:id])
if #user.update_attributes(params[:user])
flash[:success] = "Profile updated"
redirect_to #user
else
#title = "Edit" + " " + #user.username
render 'edit'
end
end
The important part was the view part and assigning the right names for the checkbox tags
<%= form_for(#user) do |f| %>
<div class="field">
<%= f.label :roles %><br />
<%= f.fields_for :role_ids do |r| %>
<% #roles.each do |role| %>
<%= check_box_tag "user[role_ids][]", role.id, #user.roles.include?(role) %>
<%= role.name %>
<% end %>
<%= hidden_field_tag "user[role_ids][]", #user.id %>
<% end %>
</div>
The check_box_tag lets the form save an array and gives more control than check_box
Then in order to assign the multiple Role ids, the name of the check_box_tag should include user[roles_ids][].
Finally the last parameter of the check_box_tag returns if the User has already the roles and checks the checkboxes if true.
I must admit that the name part of the check_box_tags is really confusing but it works :).

Possible to chain queries in Rails 3?

I have something like the following
class Group < ActiveRecord::Base
has_many :group_users
end
class GroupUser < ActiveRecord::Base
belongs_to :user, :group
end
class User < ActiveRecord::Base
has_many :group_users
end
The reason I'm not using has_many_through is because the group_user class has more information than just a link table, so I want to be able to access those values.
What I would like to do though is pass #groups to the page and loop through the group users but get at the user object as well
so
<% #groups.each do |group| %>
<%= group.group_user.user.name %>
<% end %>
Here is how I would do it:
User Model
class User < ActiveRecord::Base
has_many :memberships
has_many :groups, :through => :memberships
end
Group Model
class Group < ActiveRecord::Base
has_many :memberships
has_many :users, :through => :memberships
end
Membership Model
class Membership < ActiveRecord::Base
belongs_to :user
belongs_to :group
end
Controller
def show
#groups = Group.all
end
View
<% #groups.each do |group| %>
<% group.users.each do |user| %>
<%= user.name %>
<% end %>
<% end %>
There are probably a few ways to do it, but this should get you started.
Hope this helps!
If you want to access attributes from the GroupUser model, just do this:
<% #groups.each do |group| %>
<% group.group_users.each do |group_user| %>
<%= group_user.attribute_name %>
<%= group_user.user.name
<% end %>
<% end %>
To make this more efficient from the SQL side of things you can use eager loading:
Group.all(:includes => [:group_users => :user])
F

How to manage the form of a model that has two foreign keys

Basically I have two models: User and Godfather. The godfather table has three columns:
user_id (FK --> User)
user_godfather_id (FK --> User)
description (text)
Inside each model class, I am adding the following associations:
class User < ActiveRecord::Base
has_many :godfathers # for user_id
has_many :other_godfathers, :foreign_key => "user_godfather_id", :class_name => "Godfather"
accepts_nested_attributes_for :godfathers
end
class Godfather < ActiveRecord::Base
belongs_to :user
belongs_to :user_godfather, :class_name => "User"
end
Now my question is about how to manage the edit form of this nested attribute relationships.
Here is how my form looks like at the moment (using the nested_form_for gem):
<%= nested_form_for #user do |f| %>
<%= f.fields_for :godfathers do |godfather_form| %>
# Here I have an ID text field but what I want instead is
# to provide a username for this godfather.
<%= godfather_form.label :user_godfather_id %>
<%= godfather_form.text_field :user_godfather_id %>
<%= godfather_form.label :description %>
<%= godfather_form.text_field :description %>
<%= godfather_form.link_to_remove "Remove this godfather" %>
<% end %>
<%= f.link_to_add "Add a godfather", :godfathers %> <br/><br/>
<%= f.submit "Update Godfathers" %>
So as I said in the comments, my goal is to be able to provide a username for the godfather instead of an id. That username is a column in the User table by the way.
Any idea about how I should go about it?
Thanks!
Just use different names for the relations
class User < ActiveRecord::Base
has_many :godfathers # for user_id
has_many :some_other_godfathers, :foreign_key => "user_godfather_id", :class_name => "Godfather"
accepts_nested_attributes_for :godfathers
end
Now you can use godfathers and some_other_godfathers.
Hope that helps :-)