2017-06-29 1 views
1

Vous souhaitez appeler une méthode de scenario.rb qui contient une méthode appelée complete_scenario? qui retourne un booléen dans le fichier de migration mais une erreur indique que complete_scenario? est undefined_method.Rails: Appel d'une méthode à partir d'un modèle dans Rails Migration

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 

Y at-il quelque chose que je fais mal ou oublier d'inclure? En fin de compte, je veux ajouter une nouvelle colonne à Scenario appelée complete qui prend le booléen de Scenario et le met dans la table mise à jour. Merci.

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 

Répondre

0

Changez votre 'haut', il ressemble à ci-dessous:

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 

OU

Une meilleure approche est de remplir/SEED la nouvelle colonne dans db/seed.rb ,

Modifiez votre 'up' dans le fichier de migration ci-dessous:

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

Dans db/seed.rb ajouter cette ligne (ou vous pouvez utiliser une tâche de coupe séparé pour ci-dessous):

RailsCasts explanation here

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

Référencer noms de modèle dans les migrations n'est pas recommandé parce que les modèles sont susceptibles de changer et de retraite, alors que les migrations devraient rester statiques, et, quand ils changent, peut avoir des ramifications. – progfan

0

Référencer noms de modèle dans les migrations n'est pas recommandé parce que les modèles sont sensibles changer et prendre sa retraite, alors que les migrations devraient rester statiques et, lorsqu'elles changent, avoir des ramifications.

Donc, en général, ActiveRecord::Migration ne devrait pas se préoccuper du ActiveRecord::Base.

Je ne sais pas ce que unlabeled_choices, no_goal_nodes?, regular_leaf_nodes ou unconnected_nodes faire en interne, mais, si possible, vous devez utiliser la appropriée (série de) base de données se joindre à (s) pour remplir l'attribut :complete avec.

0

En fait, je l'ai résolu en faisant ceci:

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 
+0

L'approche consistant à référencer directement un modèle 'ActiveRecord :: Base' dans une migration est fortement déconseillée. S'il vous plaît examiner cette réponse: https://stackoverflow.com/questions/44835321/rails-call-a-method-from-a-model-in-rails-migration#answer-44840153 – progfan