我正在制作一个相对复杂的填字游戏求解器 Rails 应用程序,但这个问题只与它的两个交互模型有关:填字游戏和单元格。
计划:
在创建填字游戏之前,我让它填充了等于其(行 * 列)的单元数。然后在为该拼图填充所有单元格之后,每个单元格都与与其相邻的单元格相关联。
这是 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!
触发一次,但单元格-单元格关联并没有得到保存。
如果我在为数据库播种后运行 Crossword.first.link_cells ,则所有单元格都完美链接。这是完全相同的过程,但一个是在:after_create
过滤器中发生的,另一个是我在 Rails 控制台中输入的。
问题:
为什么.link_cells
在我创建填字游戏后 Rails 控制台可以工作,但不能在:after_create
填字游戏对象的过滤器中工作?