为什么klass.create(捐赠者)总是创建一个新的捐赠者,而donor_controller #create却没有

时间:2011-10-08 00:27:50

标签: ruby-on-rails ruby-on-rails-3

当我从我的视图中的表单转到我的donor_controller #create时,如果它匹配ID或我的find_by _ *中的列集合,它将更新记录

但如果我从不同的控制器调用该创建,它总是会创建新的记录。

我的donor_controller有一个创建方法:

  def create
    # need to find donor by id if given, else use find_or_create_by_blahblahblah
    unless @donor = Donor.find_by_id(params[:donor][:id])
      @donor = Donor.find_or_initialize_by_company_and_prefix1_and_first_name1_and_last_name1_and_address1(params[:donor])
    end
    if @donor.new_record?  
       ...
    else
       ...
    end
  end

我的其他控制人员:

 class_name = 'Donor'
 klass = ActiveRecord.const_get(class_name)  
   ... code to populate myarray with appropriate values
 klass.create(myarray)

我很确定myarray中填充了必要的参数,因为它创建了有效记录,所有内容都在正确的位置。我甚至可以不止一次地运行相同的记录,它会创建重复(当然Donor.id除外)记录。

我在这里做错了什么?

我注意到我可以在我的其他控制器中执行此操作并且它可以正常工作,但为什么我不能从donor_controller调用create并让它工作而不总是创建新记录?

#klass.create(myarray)
@mydonor = klass.find_or_initialize_by_company_and_prefix1_and_first_name1_and_last_name1_and_address1(myarray) 
@mydonor.save

1 个答案:

答案 0 :(得分:2)

您的问题非常不明确且难以理解,因此我不确定我的答案是否符合您的需求。看起来你把控制器#create方法与模型#create方法混淆了。

在模型上:这是一个类方法

create,顾名思义,实例化new类的Donor对象,并在其上调用save

@donor = Donor.create
# is the same thing as
@donor = Donor.new
@donor.save

Active Record使用new_record?来确定当您在实例化记录上调用save时是否应对数据库执行插入或更新。因此,对于create总是是一个插入,因为记录不可避免地是新的;但是如果你在从数据库中检索到的记录上调用save,它将被更新。

在控制器上:这是一个实例方法

...但不直接管理持久性,这是模型的作用。这是该控制器的动作;为了RESTful naming conventions,它被称为create。当POST请求被路由到控制器实例时,在控制器实例上调用create;其目的是管理该请求,通常(但并非总是)意味着使用YourModelName.newYourModelName.create 使用适当的模型创建记录。

因此绝对有可能(但不可取):

class DonorsController < ApplicationController
  def create
    # only works well if params[:donor][:id] is nil,
    # will raise an error if a record with the  
    # same id exists in the database
    @donor = Donor.create(params[:donor]) 
  end
end

因为通常需要在保存记录之前执行多个操作,并检查保存是否成功,该过程将被分解:

class DonorsController < ApplicationController
  def create
    @donor = Donor.new(params[:donor])
    # perform operations on @donor (instance of Donor class)
    if @donor.save # save returns true if successfully performed, false either
      # all is fine
    else
      # @donor could not be saved
    end
  end
end