我应该如何从不同的控制器(或模型)更新一个模型(表)

时间:2011-10-07 17:56:41

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

我有一个通用的导入表,允许将csv文件加载到导入表的不同列中。相同的导入表用于多种类型的导入,因此在用户准备好之前我不会处理单个字段,并告诉我在哪里处理它。

所以在这种情况下,我有一个包含许多单元格的导入表,我将使用它来创建(或更新)捐赠者表中的捐赠者。如何将与import_table模型和控制器关联的import_table数据发送到donor_controller的create方法?

我的donor_controller的create方法:

      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?   

          respond_to do |format|
            if @donor.save
              format.html { redirect_to @donor, notice: 'Donor was successfully created.' }
              format.json { render json: @donor, status: :created, location: @donor }
            else
              format.html { render action: "new" }
              format.json { render json: @donor.errors, status: :unprocessable_entity }
            end
          end    
        else
          respond_to do |format|
            if @donor.save
              format.html { redirect_to @donor, notice: 'Donor already exists.  Please edit donor if needed.'}
              format.json { render json: @donor, status: :created, location: @donor }
            else
              format.html { render action: "new" }
              format.json { render json: @donor.errors, status: :unprocessable_entity }
            end
          end 
        end   

      end

然后在我的import_tables控制器中我有这个方法:

def process_import
  @import = ImportTable.find(params[:id])
  if @import.import_type == 'Prospects'
     #do something here....
  elsif @import.import_type == 'Donations'
     #do something here...
  end

end

我不确定在#do something here...部分应该做些什么。

我在想我应该从@import中选出正确的列并将它们放在[:donor]数组中并将它们发送到我的donor_controller的create方法,但我不确定如何做到这一点或者如果是正确的方法。

2 个答案:

答案 0 :(得分:2)

缺少的链接是你需要从它的名字到达Class ..

有几种方法可以做到这一点,例如:使用“eval”,但更简洁的方法是:

# do something:
  class_name = @import.import_type
  klass = ActiveRecord.const_get(class_name)  # now you have a reference to your class

  #... then do whatever you like with your symbolic klass, e.g. create your new entry
  #  klass.find_or_create(...) , klass.find(1), klass.first ,
  #  klass.create( {attributes for new instance of klass} )

这很方便,因为在你的模型中你做了YourClass< ActiveRecord :: Base, 您的类是ActiveRecord模块的一部分,Ruby中的类是常量,它们存储在定义它们的上下文中(=在它们的模块中),因此您可以查询该上下文,例如ActiveRecord,找到你的班级。

如果您的类不是从ActiveRecord :: Base派生的,您仍然可以执行:

 klass = Kernel.const_get( class_name )

另见:     http://infovore.org/archives/2006/08/02/getting-a-class-object-in-ruby-from-a-string-containing-that-classes-name/

答案 1 :(得分:1)

如果你一行一行,请记住你正在处理哪一行。

然后在你的#do某个区域只需要调用Prospect.new,Donation.new等等。

验证或保存它,并收集对象报告的所有错误,以便您可以使用行号将其发送回用户。

您无需为每种类型转到特定的控制器方法。您的导入逻辑基本上将处理它。