Rails - HABTM relationship...Storing Checkbox Values from Users
Im trying to figure out this HABTM relationship issue to store in the interests of users within my database. The interests table has a list of different interests with id and name (i.e: id=1 , name = 'Music')
I have a users model => user.rb
has_and_belongs_to_many :interests
and an interests model => interest.rb
has_and_belongs_to_many :users
Now I'm trying to edit or update the users choice of interests from a list of checkboxes. The controller looks like so =>
def edit
#@interests = Interest.find(:all)
@title = "Edit Interest"
@user = User.find(session[:user_id])
@user.interest ||= Interest.new
interest = @user.interest
if param_posted?(:interest)
if @user.interest.update_attributes(params[:interest])
flash[:notice] = "Changes saved."
redirect_to :controller => "users", :action => "index"
end
end
end
and the param_posted function looks like this
def param_posted?(sym)
request.post? and params[sym]
end
The view logic looks like this:
<% for interest in @interest %>
<div>
<%= check_box_tag "user[interest_id][]", interest.id, @user.interests.include (interest) %>
<%= interest.name %>
</div>
<% end开发者_运维问答 %>
I thought everything looked kosher but when I run the view I get the error :
NoMethodError in InterestController#edit - undefined method `interest' for # User:0x4797ddc
Do i need to create a separate model/table that connects the interest of users to events? like InterestsofUsers ( id, user_id, interest_id)? I thought the HABTM relationship would eliminate the need for that...
Confused
There are a couple issues. First, you do need to create a join table for interests and users. Its name is combination of the two tables, in alphabetical order. It must not have a primary key. Here's an example:
class CreateInterestsUsersJoinTable < ActiveRecord::Migration
self.up
create_table :interests_users, :id => false do |t|
t.integer :interest_id
t.integer :user_id
end
end
self.down
drop_table :interests_users
end
end
Naming the join table this specific way is how Rails knows how to find it automatically.
Also, remember that a user doesn't have one interest, a user has many. That's why there's no @user.interest
method. There is a @user.interests
method, which returns an array of all the interests of that user, which you can cycle through as needed.
Aside from that, I'd really make your controller more RESTful. That edit action is trying to handle at least 2 different kinds of requests, edit AND update, when they should be separate.
After you get this part fixed, post another question about how to make your controller more restful, and I or someone else can help you there. It's better to keep the two issues in separate questions for those who search the stackoverflow database in the future.
UPDATE: questions about many-to-many relationships in Rails have come up often enough that I wrote an article called basic many-to-many associations to explain how to use habtm
vs has_many :through
, and the differences between them.
- join table - interests_users
- user has....to_many, so it's plural, you'll need to make there a list of checkboxes
- try to stick to RESTful conventions :) post should go to update method
精彩评论