4

データを入力するために、レールでグリッドを構築しようとしています。行と列があり、行と列はセルで結合されています。私の見解では、グリッドがエッジに「新しい」行と列を持つことを処理できるようにする必要があるため、それらを入力して送信すると、それらは自動的に生成され、共有セルがそれらに正しく接続されます. JSなしでこれを実行できるようにしたい。

Rails のネストされた属性は、新しいレコードと新しい列の両方にマップされていることを処理できません。どちらか一方しか実行できません。その理由は、それらが 2 つのモデルの 1 つに特にネストされており、ネストされていない方には ID がなく (まだ存在しないため)、最上位の Grid モデルで accept_nested_attributes_for を介してプッシュされるためです。 、ネストされたもののために作成された新しいオブジェクトにのみバインドされます。

どうすればこれを処理できますか? ネストされた属性のレール処理をオーバーライドする必要がありますか?

私のモデルは次のようになります。

class Grid < ActiveRecord::Base
  has_many   :rows
  has_many   :columns
  has_many   :cells, :through => :rows

  accepts_nested_attributes_for :rows,
    :allow_destroy => true,
    :reject_if => lambda {|a| a[:description].blank? }
  accepts_nested_attributes_for :columns,
    :allow_destroy => true,
    :reject_if => lambda {|a| a[:description].blank? }
 end


 class Column < ActiveRecord::Base
   belongs_to :grid
   has_many :cells, :dependent => :destroy
   has_many :rows, :through => :grid
 end

 class Row < ActiveRecord::Base
   belongs_to :grid
   has_many   :cells, :dependent => :destroy
   has_many   :columns, :through => :grid

   accepts_nested_attributes_for :cells
 end


 class Cell < ActiveRecord::Base
   belongs_to :row
   belongs_to :column
   has_one    :grid, :through => :row
 end
4

1 に答える 1

0

ほんの数日前に同様の問題に直面しましたが、二重の入れ子の問題を回避する方法はありません。問題の「メンタル」モデルを変えることで、それを乗り越えました。私がしたことを振り返り、それをあなたの状況に翻訳する際に、私が取ったアプローチは次のとおりです。

class Grid < ActiveRecord::Base
  has_many cells
  has_many rows :through => :cells
  has_many columns :through => :cells

  accepts_nested_attributes_for :cells, :allow_destroy => true
end

class Cell
  has_one column
  has_one row
  belongs_to grid
end

class Column
  has_and_belongs_to_many cells
end

class Row
  has_and_belongs_to_many cells
end

次のようなステートメント/メソッドを介して、必要な機能の一部を取得します。

a_row = Grid.cells.where("row_id = a_cell.row_id")

def remove  # an instance method for Row
   self.cells.each do |cell|
       cell.delete
   end
end

def add_column  # an instance method for Grid
    self.column_count += 1
    self.row_count.times do |i|
       cell.new(:column_id => :self.column_count, :row_id => :i)
       cell.save
    end
end

グリッドで実行する列および行指向の操作の多くは、共通の row_id または column_id を持つセルのコレクションを作成するために作成するメソッドとスコープを使用して実行する必要があります。

これがあなたのケースで正確に機能するかどうかはわかりませんが、いくつかの異なるモデルアプローチで役立つかもしれません. 幸運を。

于 2012-04-04T06:22:52.867 に答える