0

我確定這是一個簡單的問題,但我無法弄清楚它爲什麼不起作用。我有兩個型號RecipeInstructionInstructionImage。他們有一個1:n的關係,我希望這些關聯被命名爲imagesinstruction。我的模型:在rails中命名has_many/belongs_to關聯失敗

class RecipeInstruction < ActiveRecord::Base 
    belongs_to :recipe 
    has_many :images, class_name: 'InstructionImage', autosave: true, inverse_of: :instruction 
    accepts_nested_attributes_for :images 
end 

class InstructionImage < ActiveRecord::Base 
    belongs_to :chef 
    belongs_to :instruction, class_name: 'RecipeInstruction', inverse_of: :images, foreign_key: :instruction_id 
    mount_uploader :file, PictureUploader 

    validates :chef_id, presence: true 
    validates :file, presence: true 
    validates :instruction_id, presence: true 
end 

但下面的代碼失敗:

instruction = RecipeInstruction.new({"id"=>"", "text"=>"", "position"=>"0", "images_attributes"=>{"0"=>{"file"=>'test.png'}}}) 
expect(instruction).to be_an_instance_of(RecipeInstruction) 

Failure/Error: instruction = RecipeInstruction.new({"id"=>"", "text"=>"", "position"=>"0", "images_attributes"=>{"0"=>{"file"=>'test.png'}}}) 

NoMethodError: 
undefined method `val' for "?":Arel::Nodes::BindParam 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/relation.rb:574:in `block (2 levels) in where_values_hash' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/relation.rb:570:in `fetch' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/relation.rb:570:in `block in where_values_hash' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/relation.rb:563:in `map' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/relation.rb:563:in `where_values_hash' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/relation.rb:581:in `scope_for_create' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/associations/collection_association.rb:483:in `create_scope' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/associations/association.rb:168:in `initialize_attributes' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/associations/association.rb:248:in `block in build_record' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/core.rb:274:in `initialize' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/inheritance.rb:61:in `new' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/inheritance.rb:61:in `new' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/reflection.rb:130:in `build_association' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/associations/association.rb:247:in `build_record' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/associations/collection_association.rb:130:in `build' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/nested_attributes.rb:465:in `block in assign_nested_attributes_for_collection_association' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/nested_attributes.rb:460:in `each' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/nested_attributes.rb:460:in `assign_nested_attributes_for_collection_association' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/nested_attributes.rb:343:in `images_attributes=' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/attribute_assignment.rb:54:in `public_send' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/attribute_assignment.rb:54:in `_assign_attribute' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/attribute_assignment.rb:65:in `block in assign_nested_parameter_attributes' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/attribute_assignment.rb:65:in `each' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/attribute_assignment.rb:65:in `assign_nested_parameter_attributes' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/attribute_assignment.rb:45:in `assign_attributes' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/core.rb:551:in `init_attributes' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/core.rb:272:in `initialize' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/inheritance.rb:61:in `new' 
/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/inheritance.rb:61:in `new' 
./spec/recipe_instruction_spec.rb:9:in `block (2 levels) in <top (required)>' 

我發現,沒有定義foreign_key列的解決方案,但我做到了。我在/Users/alias/.rvm/src/rvm/gems/ruby-2.1.6/gems/activerecord-4.2.0.beta2/lib/active_record/relation.rb

def where_values_hash(relation_table_name = table_name) 
    equalities = where_values.grep(Arel::Nodes::Equality).find_all { |node| 
    node.left.relation.name == relation_table_name 
    } 

    binds = Hash[bind_values.find_all(&:first).map { |column, v| [column.name, v] }] 

    Hash[equalities.map { |where| 
    name = where.left.name 
    puts 'debug' 
    puts @klass.inspect 
    puts @table.inspect 
    puts name.inspect 
    puts where.inspect 
    [name, binds.fetch(name.to_s) { 
     case where.right 
     when Array then where.right.map(&:val) 
     else 
     where.right.val 
     end 
    }] 
    }] 
end 

這裏調試這個調試:

InstructionImage(id: integer, file: string, chef_id: integer, instruction_id: integer, created_at: datetime, updated_at: datetime) 

#<Arel::Table:0x007f9ec4a9d688 @name="instruction_images", @engine=InstructionImage(id: integer, file: string, chef_id: integer, instruction_id: integer, created_at: datetime, updated_at: datetime), @columns=nil, @aliases=[], @table_alias=nil, @primary_key=nil> 

"recipe_instruction_id" 

#<Arel::Nodes::Equality:0x007f9ec4a155a8 @left=#<struct Arel::Attributes::Attribute relation=#<Arel::Table:0x007f9ec4a15f30 @name="instruction_images", @engine=ActiveRecord::Base, @columns=nil, @aliases=[], @table_alias=nil, @primary_key=nil>, name="recipe_instruction_id">, @right="?"> 

爲什麼名字recipe_instruction_id。關係名稱是instruction,我已將其外鍵定義爲instruction_id。這是錯誤嗎?我該如何解決它?

謝謝

回答

1

您應該在RecipeInstruction類中定義foreign_id。

class RecipeInstruction < ActiveRecord::Base 
    belongs_to :recipe 
    has_many :images, class_name: 'InstructionImage', autosave: true, foreign_key: "instruction_id" 
    accepts_nested_attributes_for :images 
end 
+0

非常感謝,它做到了!但是爲什麼沒有'inverse_of::指令的竅門?你爲我節省了很多時間,但我無法理解它。 – noeden