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

时间:2022-08-20 01:14:29

In my Rails 4 app I have this controller:

在我的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

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?

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

Thanks for any help.

感谢任何帮助。

3 个解决方案

#1


3  

This kind of constraint:

这种约束:

Create/update an associated object B on each create/update of Model A

在每次创建/更新模型A时创建/更新关联的对象B

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.

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


So, in your case, you can combine an after_create and an after_save in your Invoice model:

因此,在您的情况下,您可以将after_create和after_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

#2


0  

You are probably looking for first_or_create.update

您可能正在寻找first_or_create.update

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

#3


-1  

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

#1


3  

This kind of constraint:

这种约束:

Create/update an associated object B on each create/update of Model A

在每次创建/更新模型A时创建/更新关联的对象B

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.

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


So, in your case, you can combine an after_create and an after_save in your Invoice model:

因此,在您的情况下,您可以将after_create和after_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

#2


0  

You are probably looking for first_or_create.update

您可能正在寻找first_or_create.update

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

#3


-1  

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