2013-05-06 87 views
1

当创建下面的对象“Machine”时,得到ActiveRecord :: AssociationTypeMismatch Component(#70354292616060) expected, got String(#70354278277000);ActiveRecord :: AssociationTypeMismatch创建新时

目标:尝试将“属性”分配给引用其他模型的模型。

问题:我想听取专家的意见,这种手术的最佳做法是什么。

设置

导轨3.2.12 /红宝石1.9.3-P194:

型号:

class Machine < ActiveRecord::Base 
    attr_accessible :cpu, :name, :ram 

    belongs_to :cpu, class_name: "Component", foreign_key: "component_id" 
    belongs_to :ram, class_name: "Component", foreign_key: "component_id" 
end 

class Component < ActiveRecord::Base 
    attr_accessible :name 
    has_many :machines 
end 

查看用于机器:

<div class="field"> 
    <%= f.label :name %><br /> 
    <%= f.text_field :name %> 
    </div> 
    <div class="field"> 
    <%= f.label :cpu %><br /> 
    <%= f.collection_select :cpu, Component.all, :id, :name %> 
    </div> 
    <div class="field"> 
    <%= f.label :ram %><br /> 
    <%= f.collection_select :ram, Component.all, :id, :name %> 
    </div> 
    <div class="actions"> 
    <%= f.submit %> 
    </div> 

程序

  1. 创建于组件几个对象,使得id:1 name:"cpu1" & id:2 name:"ram1"
  2. 转到machines_path并从下拉选择CPU1及RAM1下来
  3. 了以下错误创建机器时提交Component(#70354292616060) expected, got String(#70354278277000)

我尝试改变:cpu和:ram在View中:cpu_id和:ram_id。之后,我可以无误地创建模型。但是我无法直接从机器访问cpu & ram;

1.9.3-p194 :001 > Machine.first 
    Machine Load (0.1ms) SELECT "machines".* FROM "machines" LIMIT 1 
=> #<Machine id: 2, name: "test", cpu_id: 1, ram_id: 1, created_at: "2013-05-06  16:42:47", updated_at: "2013-05-06 16:42:47"> 
1.9.3-p194 :002 > Machine.first.cpu 
    Machine Load (0.2ms) SELECT "machines".* FROM "machines" LIMIT 1 
=> nil 
1.9.3-p194 :003 > Machine.first.ram 
    Machine Load (0.2ms) SELECT "machines".* FROM "machines" LIMIT 1 
=> nil 

所以我不得不创建以下模型方法

class Machine < ActiveRecord::Base 

    (snip) 

    def cpu 
    Component.find_by_id(self.cpu_id) 
    end 

    def ram 
    Component.find_by_id(self.ram_id) 
    end 

然后我就可以得到预期的输出

1.9.3-p194 :002 > Machine.first.cpu.name 
    Machine Load (0.2ms) SELECT "machines".* FROM "machines" LIMIT 1 
    Component Load (0.2ms) SELECT "components".* FROM "components" WHERE "components"."id" = 1 LIMIT 1 
    => "CPU1" 

但我觉得这是多余的,找一个更简单的方法来做到这一点。

欣赏是否有任何建议。

+0

您应该看看nested_attributes;) – MrYoshiji 2013-05-06 17:06:43

+0

谢谢MrYoshiji对于你的建议,会试试看。 – charles 2013-05-06 17:49:26

回答

0

首先,让您的选择框与CPU_ID和ram_id工作是正确的事做。如果你不那么轨器会(稍微简化)做

machine.cpu = params[:machine][:cpu] 

PARAMS总是字符串,所以这是试图将一个字符串分配给关联,因此它期待一个组成部分,但得到的字符串错误。

你的第二个问题是你如何宣布你的关联:你已经设置了ram和cpu关联,以使用component_id列来存储相应列的id,这显然无法工作。相反,您可能希望CPU关联使用cpu_id列和ram关联ram_id列。这实际上是默认的 - 删除你传递给这些呼叫的外键选项,你应该没问题。

虽然组件上的关联需要外键选项。最简单的事情是将一个组件用作CPU,另一个用于RAM。你可能会考虑设置单表继承,在这种情况下,CPU子类只会有与cpu_id相关的关联,而ram子类只会与ram_id有关联。

+0

非常感谢Fredrick的建议。它改变了外键后,所有预期的工作。 (没有冗余模型方法)。 – charles 2013-05-07 03:35:25

0

所以,如果我正在阅读这个权利,你需要能够在你的表单中设置字段到另一个模型。

这是嵌套的属性。

form_for @machines内的form_for @componentsMachine模型给attr_accessible权限,这些领域

,这是很有帮助http://railscasts.com/episodes/196-nested-model-form-part-1

+0

我不应该忽略那部分。 form_for和attr_accessible被设置。表的Machine有一个名为“cpu_id:integer”和“ram_id:integer”并且attr_accessible :: cpu_id,:ram_id的列。 – charles 2013-05-06 17:47:37

相关问题