关联:现有表格中的一对多

时间:2014-06-06 12:17:54

标签: ruby-on-rails activerecord ruby-on-rails-4

Rails初学者:

我已经有了一个数据库和表,所以命名约定给我带来了一些麻烦

class Item < ActiveRecord::Base    
  belongs_to :categorie, :foreign_key => "catid"   
end

class Categorie < ActiveRecord ...    
  has_many :item
end

i = Item.first    # Ok

c = i.Categorie   # Ok,  finds proper Categorie based on "catid" of i

c.Item # fails with Categorie_id column not found ! how can i map Categorie_id to "catid"?

3 个答案:

答案 0 :(得分:1)

你是初学者,但你可能不是程序员初学者,所以我会潜入并解释一下课程。

A class只是一个包含方法的数据对象。而已。这是一个简单的方法,它包含一种方法:

class Cow
    def talk
        "moo"
    end
end

Cow是类,talk是方法。现在,如果我们在内存中有上述类,我们就无法在控制台中执行此操作:

talk

因为该方法在全球范围内不可用。这是一件好事,因为这可能会导致错误并且效率低下。想象一下,如果我们有一些动物:

class Cat
    def talk
        "meow"
    end
end

class Dog
    def talk
        "woof"
    end
end

运行talk,计算机如何知道运行哪个talk?相反,我们将类中的方法称为:

Cow.talk #=> "moo"
Cat.talk #=> "meow"
Dog.talk #=> "woof"

希望现在,这段代码:

Item.first

不那么神秘。 Item是一个类,first是该类中可用的方法。

现在我知道Item是一个模型,但在rails中,模型只是从ActiveRecord 继承了许多有用方法的类。在Item模型的顶部,您应该看到:

class Item < ActiveRecord::Base

这是所有有用方法的内容,例如我们正在使用的first方法。由于这种继承,我们可以想象你的Item类看起来有点像这样:

class Item < ActiveRecord::Base
    def first
       # code is in here that queries the table in your database that has
       # the downcased and pluralized name of Item (so items) and returns the first
       # row of that table
    end 

    # down here is all of your methods you've probably created. Validations and the like.
end

first,而不是像我的例子中那样返回一个更有用的东西;它查询数据库中具有其类的下层和复数名称的表。因此Item.first查询items表,并返回第一行。

现在,我必须说实话,尽管你说的话,我发现i.Categorie根据&#34; catid&#34;找到合适的分类是非常值得怀疑的。我如果确实如此,我觉得你已经做了一些疯狂的解决方法来实现这个目标。这是应该发生的事情:

i.Categorie
NoMethodError: undefined method `Categorie' for #<Item:0x00000005905830>

用简单的英语,这意味着

NoMethodError: there is no 'Categorie' method inside that instance of the 'Item' class.

这是有道理的,因为我认为没有&#39;分类&#39;方法在这里:

class Item < ActiveRecord::Base
    def first
       # code is in here that queries the table in your database that has
       # the downcased and pluralized name of Item (so items) and returns the first
       # row of that table
    end 

    # down here is all of your methods you've probably created. Validations and the like.
end

现在c.Item无效的原因是因为c设置为nil,因为nil由于非i.Categorie而返回 - 方法错误,nil当然没有方法Item

c = i.Categorie # c is set to nil due to noMethodError
c.Item
NoMethodError: undefined method `Item' for nil:NilClass

希望你能更加了解现在的情况。如果您希望代码工作,您应该这样做。仔细看,有一些细微差别:

i = Item.first    # i is set to the first instance of Item
c = i.categorie   # c is set to the instance of Categorie that i belongs to
is = c.items      # returns an array consisting of all the Item instances that belong to the Categorie instance in c

我们也可以这样做:

is.first # returns i

那么所有这些方便的方法来自何处? categorie内的i方法(i.category),itemsc)内的c.items方法?答案是它们是由Rails基于您的继承动态创建的,并通过&lt;拉入相关模型。 ActiveRecord的::基地。

基于你的继承&#34;我的意思是,您如何使用继承方法belongs_tohas_many

class Item < ActiveRecord::Base    
  belongs_to :categorie, :foreign_key => "catid" # creates categorie method that returns the instance of Categorie this instance of Item belongs to    
end

class Categorie < ActiveRecord ...    
  has_many :item # creates items method that returns an array of all the instances of Item that belong to this instance of Categorie  
end

我还要指出,分类是一个非常可怕的模型名称,纯粹是因为它的拼写错误。也许Type会更好?

答案 1 :(得分:0)

你可以做到 Item.create(:catid =&gt; @ categorie.id)

@categorie = Categorie.find(params [:id])或者使用Categorie.all 放置每个循环&amp;找到id。

答案 2 :(得分:0)

首先,您应该使用类别作为模型,因为rails会智能地理解复数类别或表格。

其次,你应该有这样的东西;

class Item < ActiveRecord::Base    
  belongs_to :Category, :foreign_key => "catid"   
end

class Categorie < ActiveRecord ...    
  has_many :items
end

i = Item.first



c = i.Category



c.items #to find all items that belong to the category c
相关问题