如何在Rails中组合创建和更新操作?

时间:2015-04-07 17:47:25

标签: ruby-on-rails ruby-on-rails-4 activerecord

在我的Rails 4应用程序中,我有这个控制器:

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

基本上,在创建invoice时它会执行的操作,它还会创建一个关联的sender记录,其中包含发票的信头数据,例如公司名称,地址等。

发票更新后,其关联的发件人记录也会更新。

我只是想知道这是否可以使用过滤器或类似create_or_update()之类的函数在模型中组合?

感谢您的帮助。

3 个答案:

答案 0 :(得分:3)

这种约束:

  

在模型A的每次创建/更新

上创建/更新关联对象B.

应该由模型A持有。如果明天需要另一个页面来创建模型A的实例,则不必在两个控制器的操作中执行相同的逻辑,因为模型A负责创建模型B的相关实例。


因此,在您的情况下,您可以在发票模型中合并after_createafter_save

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

答案 1 :(得分:0)

您可能正在寻找first_or_create.update

Comment.where(user_id: 6).first_or_create.update(content: 'lorem ipsum')

答案 2 :(得分:-1)

是的,一种方法是尝试使用这样的动作参数:

def create_or_update()
  if params[:action].eql?('create')
    #code for save action
  elsif params[:action].eql?('update')
    #code for update action
  end
end