簡體   English   中英

使用一個模型批量插入

[英]Bulk insert using one model

我正在嘗試使用textarea和一個Submit按鈕創建一個表單,該表單將允許用戶進行批量插入。 例如,輸入看起來像這樣:

0001;MR A
0002;MR B

結果將如下所示:

mysql> select * from members;

+------+------+------+
|  id  |  no  | name |
+------+------+------+
|   1  | 0001 | MR A |
+------+------+------+
|   2  | 0002 | MR B |
+------+------+------+

我是Rails的新手,我不確定如何進行此操作。 我應該使用attr_accessor嗎? 如何在表單視圖中處理驗證失敗? 有什么例子嗎? 提前致謝。

更新資料

基於MissingHandle的評論,我創建了一個Scaffold並將其代碼替換為:

class MemberBulk < ActiveRecord::Base

  attr_accessor :member

  def self.columns
    @columsn ||= []
  end

  def self.column(name, sql_type = nil, default = nil, null = true)
    columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
  end

  column :data, :text

  validates :data, :create_members, :presence => true

  def create_members
    rows = self.data.split("\r\n")

    @member = Array.new

    rows.each_with_index { |row, i|
      rows[i] = row.strip
      cols = row.split(";")

      p = Member.new
      p.no = cols[0]
      p.name = cols[1]

      if p.valid?
        member << p
      else
        p.errors.map { |k, v| errors.add(:data, "\"#{row}\" #{v}") }
      end
    }
  end

  def create_or_update
    member.each { |p|
      p.save
    }
  end
end

我知道代碼還遠遠不夠完整,但是我需要知道這是正確的方法嗎?

class MemberBulk < ActiveRecord::Base

  #Tells Rails this is not actually tied to a database table
  # or is it self.abstract_class = true
  # or @abstract_class = true
  # ?
  abstract_class = true

  # members holds array of members to be saved
  # submitted_text is the data submitted in the form for a bulk update
  attr_accessor :members, :submitted_text
  attr_accessible :submitted_text

  before_validation :build_members_from_text

  def build_members_from_text
    self.members = []
    submitted_text.each_line("\r\n") do |member_as_text|
      member_as_array = member_as_text.split(";")
      self.members << Member.new(:number => member_as_array[0], :name => member_as_array[1])
    end
  end

  def valid?
    self.members.all?{ |m| m.valid? }
  end

  def save
    self.members.all?{ |m| m.save }
  end

end

class Member < ActiveRecord::Base

  validates :number,  :presence => true, :numericality => true
  validates :name,    :presence => true

end

因此,在此代碼中,成員是一個數組,該數組是單個成員對象的集合。 我的想法是,您要盡可能將工作交給Member類,因為該類實際上將綁定到數據庫表,並且可以在其上期待標准的Rails模型行為。 為了做到這一點,我重寫了所有ActiveRecord模型共有的兩種方法:save和有效。 MemberBulk僅在其所有成員均有效的情況下才有效,並且僅在所有成員均已保存時才視為已保存。 您可能還應該重寫errors方法,以返回其基礎成員的錯誤,並可能在所提交的文本中指出該成員的錯誤。

最后,我不得不從使用抽象類更改為活動模型(不知道為什么),但是當我升級到Rails v3.1時,它停止了工作。 這是工作代碼:

class MemberBulk
  include ActiveModel::Validations
  include ActiveModel::Conversion
  extend ActiveModel::Naming

  attr_accessor :input, :data

  validates :input, presence: true

  def initialize(attributes = {})no
    attributes.each do |name, value|
      send("#{name}=", value) if respond_to?("#{name}=")
    end
  end

  def persisted?
    false
  end  

  def save
    unless self.valid?
      return false
    end

    data = Array.new

    # Check for spaces
    input.strip.split("\r\n").each do |i|
      if i.strip.empty?
        errors.add(:input, "There shouldn't be any empty lines")
      end

      no, nama = i.strip.split(";")

      if no.nil? or nama.nil?
        errors.add(:input, "#{i} doesn't have no or name")
      else
        no.strip!
        nama.strip!

        if no.empty? or nama.empty?
          errors.add(:input, "#{i} doesn't have no or name")
        end
      end  

      p = Member.new(no: no, nama: nama)
      if p.valid?
        data << p
      else
        p.errors.full_messages.each do |error|
          errors.add(:input, "\"#{i}\": #{error}")  
        end        
      end             
    end # input.strip    

    if errors.empty?
      if data.any?

        begin
          data.each do |d|
            d.save
          end
        rescue Exception => e
          raise ActiveRecord::Rollback
        end

      else
        errors.add(:input, "No data to be processed")
        return false
      end
    else
      return false
    end

  end # def
end

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM