Reputation: 10207
In my Rails 4 app I have this controller:
class InvoicesController < ApplicationController
...
def create
@invoice = current_user.invoices.build(invoice_params)
@invoice.build_sender(current_user.profile.sender_fields) # <= !
if @invoice.save
flash[:success] = "Invoice created."
redirect_to invoices_path
else
render :new
end
end
def update
if @invoice.update_attributes(invoice_params)
@invoice.sender.update_attributes(current_user.profile.sender_fields) # <= !
flash[:success] = "Invoice updated."
redirect_to invoices_path
else
render :edit
end
end
...
end
Basically, what it does it when an invoice
gets created, it also creates an associated sender
record containing essentially the invoice's letterhead data, such as company name, address, etc.
When an invoice gets updated, its associated sender record gets updated as well.
I just wonder if this can be combined inside the model using a filter or a function like create_or_update()
or something similar?
Thanks for any help.
Upvotes: 3
Views: 2143
Reputation: 54882
This kind of constraint:
Create/update an associated object B on each create/update of Model A
Should be held by the Model A. If tomorrow you need another page to create instances of Model A, you will not have to do the same logic in the two controller's actions because Model A is responsible for the creation of associated instance(s) of Model B.
So, in your case, you can combine an after_create
and an after_save
in your Invoice model:
after_create :create_or_update_sender
after_update :create_or_update_sender
def create_or_update_sender
local_sender = (self.sender || self.build_sender)
local_sender.update_attributes(self.user.profile.sender_fields)
local_sender.save!
end
Upvotes: 3
Reputation: 26792
You are probably looking for first_or_create.update
Comment.where(user_id: 6).first_or_create.update(content: 'lorem ipsum')
Upvotes: 0
Reputation: 1466
Yes, one way is to try using action params like this:
def create_or_update()
if params[:action].eql?('create')
#code for save action
elsif params[:action].eql?('update')
#code for update action
end
end
Upvotes: -1