In a small app I am building, I have a controller that creates an exchange. When a user creates an exchange they are simultaneously the organizer of the exchange and a participant in the exchange. Participants are tracked by a join table that joins a user_id
and an exchange_id
. Organizers are tracked by a foreign user_id
key in the exchange table.
I am trying to figure out where to put the code that will automatically create a new membership record for the organizer of the exchange. Should I put this in the exchange_controller's create action itself, or in an after_filter
triggered by the create action? Or maybe somewhere else? Part of the problem is that I could not find any good examples of proper after_filter use (guides.rubyonrails.org only had sparse mention of it), so any links pointing in the correct direction would be appreciated as well.
Here is relevant model code:
app/models/user.rb:
# Returns array of exchanges user is participating in
has_many :participations,
:through => :memberships,
:source => :exchange
# Returns array of exchanges user has organized
has_many :organized_exchanges,
:foreign_key => :organizer_id,
:class_name => "Exchange"
app/models/membership.rb:
class Membership < ActiveRecord::Base
attr_accessible :exchange_id, :user_id, :role
belongs_to :exchange
belongs_to :user
end
app/modles/exchange.rb:
belongs_to :organizer,
:foreign_key => :organizer_id,
:class_name => "User"
has_many :memberships, :dependent => :destroy
has_many :participants,
:through => :memberships,
:source => :user
And here is the relevant controller code:
app/controllers/exchanges_controller.rb:
def create
@exchange = Exchange.new(params[:exchange])
@exchange.organizer_id = current_user.id
if @exchange.save
redirect_to exchange_path(@exchange.id)
else
render 'new'
end
end
after_filter
is a completely different thing in this context. It is called when your view is completely processed and so you want to call some action to do something.
You can use after_create
callback that is triggered when a record is created in the database.
In your case, a user is creating an exchange and so after the exchange is created, the after_create
callback is triggered and you can apply your functionality over there to make the current user who created the exchange to be a participant.
The way to write in a model is like this:
after_create :do_something
def do_something
something.do!
end
Note: It is not good to use after_save
here because it is triggered every time you save a record or even if you update a record.
There is a nice SO post that clearly tells you the difference between the after_create
and after_save
.
See this SO post for the difference between the two.
More on the callbacks is here.