Rails - Add Record to join table from controller
Solution 1
The following code should work (assuming that you pass in an parameter with the name id that corresponds to the id of an event object):
def add
@user = User.find(session[:user_id])
@event = Event.find(params[:id])
@user.events << @event
flash[:notice] = 'Event was saved.'
end
The problems I see in your code are:
You are passing a hash to .save. Save should only take a boolean value corresponding whether validations should be run and is true by default. However .create and .new can accept a hash of values. (.save would be used after .new).
You load an event through params[:id] but then you attempt to create an event through params[:user][:event]. Which do you want to do? Create or load? (my example assumes load)
Actions that have an effect such as this one should happen when a user clicks a button and submits a form rather than 'clicking a link'. This code may be vulnerable to cross site request forgery (Someone could trick someone into clicking a link on another site that ran this action). Rails forms, if correctly implemented, are protected against this because they use a request forgery protection token.
Most likely you want to redirect the user after this action. Rendering pages after executing actions like this (rather than redirecting) is considered bad practice.
Solution 2
What you did in the console you need to do in the controller.
def add
@user = User.find(session[:user_id])
@event = Event.find(params[:id])
@user.events << @event
flash[:notice] = 'Event was saved.'
end
The thing to note here is that the << operator for existing records will cause the association to be persisted immediately.
Take a look at the ActiveRecord documentation for more info.
Comments
-
ChrisWesAllen almost 2 years
I'm trying to create a record within a join table from the action of a button. I would have an events model and would like to track selected events from each user.
I used the HABTM relationship since I don't really need any extra fields.
User.rb:
has_to_and_belongs_to_many :events
Event.rb:
has_to_and_belongs_to_many :users
Events_Users Migration:
[user_id, event_id, id=>false]
I'm getting stuck on the actual creation of the record. Someone helped me earlier with adding the record in within the console:
u = User.find(1) u.events << Event.find(1)
Now I would like to perform the action as a result of clicking a link... Is this in the right direction?
def add @user = User.find(session[:user_id]) @event = Event.find(params[:id]) if @user.events.save(params[:user][:event]) flash[:notice] = 'Event was saved.' end end
Should I add a
@user.events.new
somewhere and if so where do I put the params of which user and which event? -
Gdeglin about 14 yearsNo. That code would not make sense if I am understanding your description of the problem correctly.
-
ChrisWesAllen about 14 yearsThanks for the suggestions, I changed the "<%= link_to image_tag("grid_heart.gif", :border=>0 ), :controller => 'event', :action => 'add_event' %>" to "<%= button_to "Add", :controller => 'event', :action => "add" %>" but I still get an error of there being an "uninitialized constant EventController" Did i put the method in the wrong controller?
-
ChrisWesAllen about 14 yearsIm still getting an uninitialized constant EventController Any idea where it could coming from?
-
Harish Shetty about 14 yearsCan you post your controller code at Pastie (pastie.org) and provide a link.
-
ChrisWesAllen about 14 yearsI can, but that is the only method I've added to the event_controller. There is no error when I remove the add method, and the rest of the controller was generated from a scaffold so its pretty basic stuff. The current method looks like... def add @user = User.find(session[:user_id]) @event = Event.find(params[:id]) @user.events << @event flash[:notice] = 'Event was saved.' end
-
ChrisWesAllen about 14 yearsSorry, I'm not sure how to add code snippets to a comment on stackoverflow
-
Gdeglin about 14 yearsThat code is not correct, though that's not what the cause of your error is. You use the parameter :controller => 'event', which tells rails to look for an EventController. Rails is telling you that no such controller exists in your project.
-
ChrisWesAllen about 14 yearsI think the problem is related to finding the parameter of the event...I;m not sure how to pull that data