1

私は比較的複雑なクロスワード ソルバー Rails アプリを作成していますが、この問題は、相互に作用する 2 つのモデル (Crossword と Cell) にのみ関連しています。

計画:

クロスワードを作成する前に、(行 * 列) に等しい数のセルを入力します。次に、そのパズルのすべてのセルが入力された後、各セルはそれに隣接するセルに関連付けられます。

Cell クラスの要約版を次に示します。.assign_bordering_cells各セルには、メソッドによって設定された隣接セルとの相互関係があることに注意してください。

class Cell < ActiveRecord::Base

  ....

  has_one :right_cell, class_name: 'Cell', foreign_key: 'left_cell_id', inverse_of: :left_cell
  has_one :below_cell, class_name: 'Cell', foreign_key: 'above_cell_id', inverse_of: :above_cell
  belongs_to :left_cell, class_name: 'Cell', foreign_key: 'left_cell_id', inverse_of: :right_cell
  belongs_to :above_cell, class_name: 'Cell', foreign_key: 'above_cell_id', inverse_of: :below_cell

  def assign_bordering_cells!
    puts "Assign bordering cells for cell in row #{self.row}, column #{self.col}"
    self.left_cell = self.crossword.cells.find_by_row_and_col(self.row, self.col-1) unless (self.col == 1)
    self.above_cell = self.crossword.cells.find_by_row_and_col(self.row-1, self.col) unless (self.row == 1)
    self.save
  end
end

そして、これがクロスワードクラスの要約です。セルにデータを入力した後、.link_cellsメソッドはそれらすべてのセルを反復処理し、それらを隣接するセルにリンクする必要があります。

class Crossword < ActiveRecord::Base
  before_create :populate_cells
  after_create :link_cells

  ...

  def populate_cells
    row = 1
    while (row <= self.rows)
      col = 1
      while (col <= self.cols)
        self.cells << Cell.new(row: row, col: col, is_across_start: col == 1, is_down_start: row == 1)
        col += 1
      end
      row += 1
    end
  end

  def link_cells
    self.cells.each {|cell| cell.assign_bordering_cells! }
  end

end

最終結果は、各セルがその上、下、左、右にあるセルを「認識」する必要があります。これらの隣接セルの 1 ~ 2 個が欠落している可能性があるエッジ セルを考慮しました。

ヒッチ:

データベースに新しいクロスワードをシードすると、セルが正しく作成されます。ただし、.link_cellsは確実に呼び出され.assign_bordering_cells!、セルごとに 1 回トリガーされますが、Cell-Cell 関連付けは保存されません。

データベースをシードしたで Crossword.first.link_cells を実行すると、すべてのセルが完全にリンクされます。まったく同じプロセスですが、1 つは:after_createフィルターで発生しており、もう 1 つは Rails コンソールに入力しています。

質問:.link_cellsクロスワードを作成した後、Rails コンソールでは機能するのに、:after_createクロスワード オブジェクトのフィルターでは機能 しないのはなぜですか?

4

0 に答える 0