Rails: 从 Rails 迁移中的模型调用方法

Rails: Call a method from a model in Rails Migration

试图从 scenario.rb 调用一个方法,其中包含一个名为 complete_scenario 的方法?其中 returns 是迁移文件中的布尔值,但错误指出 complete_scenario? 是 undefined_method。

class AddCompleteFlagToScenarios < ActiveRecord::Migration

def up
change_table :scenarios do |s|
  s.boolean :complete, s.complete_scenario? :default => false, :null =>false
end

end

def down
  remove_column :scenarios, :complete
end

end

有什么我做错了或忘记包括的吗?最后,我想向 Scenario 添加一个名为 complete 的新列,它从 Scenario 中获取布尔值并将其放入更新后的 table。 谢谢。

class Scenario < ActiveRecord::Base
validates :name,
presence: true,
uniqueness: { :case_sensitive => false },
length: { in: 4..60 }

has_many :nodes
has_many :showings, -> { visible }
has_many :courses, :through => :showings

attr_accessor :warnings

amoeba do
enable
include_association [:nodes]
end

...

def complete_scenario?
   (self.unlabeled_choices.empty?) && (self.no_goal_nodes?) && (self.regular_leaf_nodes.empty?) && (self.unconnected_nodes.empty?)
end

更改您的 'up',使其如下所示:

def up
 change_table :scenarios do |s|
  #here s is not ActiveRecord object, rather refers to table, s.complete_scenario? is invalid here, so instead do below
  s.boolean :complete, :default => false, :null =>false
 end
 #here you set the complete field for all rows in the table
 Scenario.find_each do |s| 
   s.complete = s.complete_scenario?
   s.save!
 end
end

更好的方法是 populate/seed db/seed.rb 中的新列,

将迁移文件中的 'up' 更改为以下内容:

def up
 change_table :scenarios do |s|
  s.boolean :complete, :default => false, :null =>false
 end
end

在 db/seed.rb 中添加这一行(或者您可以在下面使用单独的 rake 任务):

RailsCasts explanation here

 Scenario.find_each do |s| 
   s.complete = s.complete_scenario?
   s.save!
 end

不建议在迁移中引用模型名称,因为模型容易发生变化和退役,而迁移应该保持静态,并且当它们发生变化时,可能会产生影响。

所以,一般来说,ActiveRecord::Migration 不应该关心 ActiveRecord::Base

我不知道 unlabeled_choicesno_goal_nodes?regular_leaf_nodesunconnected_nodes 在内部做什么,但是,如果可能,您应该使用适当的(系列的)数据库连接以填充 :complete 属性。

其实我是这样解决的:

def up

  add_column :scenarios, :complete, :boolean

  Scenario.find_each do |s|
    s.complete = s.complete_scenario?
    s.save!
  end

end

def down
   remove_column :scenarios, :complete
end