如何使用Ruby on Rails设置嵌套模型?

时间:2013-05-13 12:18:03

标签: ruby-on-rails ruby model nested

我是编码的新手,我发现了RoR。 我想用Users和Products创建一个应用程序。我很擅长用户,但我想知道产品的架构......

这里是我想象的产品型号:

Product :

- Name
- Owner
- Borrower
- Location
    - Address
    - GPS Coordinates
- Comments
    - Title
    - Content
    - User
- Category

这是我的主要模特:

Class User
    has_many :owned_products, class_name: "Product", foreign_key: "owner_id"
    has_many :borrowed_products, class_name: "Product", foreign_key: "borrower_id"
    has_one :location, as: :localizable
end

$ rails generate model Location address:string coordinates:string
Class Location
    belongs_to :localizable, polymorphic: true
end

$ rails generate model Comment title:string content:text user_id:integer
Class Comments
    belongs_to :product
    has_one :user
end

$ rails generate model Product name:string owner_id:integer borrower_id:integer location_id:integer comment_id:integer category_id:integer
Class Product
    belongs_to :owner, class_name: "User", foreign_key: "owner_id"
    belongs_to :borrower, class_name: "User", foreign_key: "borrower_id"
    has_one :location, as: :localizable
    has_many :comments
    has_one :category
end

所以,我想知道我是否必须创建这样的每个类别子模型:

- Consumption
    - Name
    - Utility
    - Builder
- Culture
    - Title
    - Barcode
    - Type
        - Book
            - Author
            - Publisher
        - Video
            - Length
            - Format
- Food
    - Name
    - Cooking Date
    - Weight

我会写下这样的话:

$ rails generate model Category consumption_id:integer culture_id:integer food_id:integer
Class Category
    belongs_to :product
    has_one :consumption
    has_one :culture
    has_one :food
end

  $ rails generate model Consumption name:string utility:string builder:string
  Class Consumption
      belongs_to :category
  end


  $ rails generate model Culture title:string barcode:integer type_id:integer
  Class Culture
      belongs_to :category
      has_one :type
  end

    $ rails generate model Type book_id:integer video_id:integer
    Class Type
        belongs_to :culture
        has_one :book
        has_one :video
    end

      $ rails generate model Book author:string publisher:string
      Class Book
          belongs_to :type
      end

      $ rails generate model Video length:string format:string
      Class Video
          belongs_to :type
      end

  $ rails generate model Food name:string cooking_date:datetime weight:float
  Class Food
      belongs_to :category
  end

或者如果将它保持在这样的一个级别会更好:

- Category_type (consumption, culture, or food)
- Name (or title)
- Utility
- Builder
- Barcode
- Culture_type
- Author
- Publisher
- Length
- Format
- Cooking_date
- Weight

会给我:

$ rails generate model Category category_type:string name:string utility:string builder:string barcode:integer culture_type:string author:string publisher:string length:integer format:string cooking_date:datetime weight:float
Class Category
    belongs_to :product
end

我觉得第一种方式更容易理解,但我怀疑它会和第二种方式一样高效。你能给我一个暗示吗?


相应于@ r4m,这就是我所做的:

$ rails generate model Category
Class Category
    belongs_to :product
    belongs_to :categorizable, polymorphic: true
end

  $ rails generate model Consumption name:string utility:string builder:string
  Class Consumption
      has_many :categories, :as => :categorizable
  end


  $ rails generate model Culture title:string barcode:integer type_id:integer
  Class Culture
      has_many :categories, :as => :categorizable
      has_one :type
  end

  $ rails generate model Food name:string cooking_date:datetime weight:float
  Class Food
      has_many :categories, :as => :categorizable
  end

我将类别的迁移更改为:

class CreateCategories < ActiveRecord::Migration
  def change
    create_table :categories do |t|
      t.references :categorizable, polymorphic: true
      t.timestamps
    end
  end
end

但这对我来说似乎不太明白......

如果我想抓住@user的每一个“消费”产品,我该怎么办?做那样的事情能够奏效吗?

@consumptions = @user.products.consumptions

1 个答案:

答案 0 :(得分:2)

假设您有一系列属于同一类别的食物(以及相同的消费和文化参数)。对于最后一个模型,您有很多冗余,因为您无法将数组分配给一行,在本例中是一个Category表的行(请参阅here以获取Rails支持的类型)。您将被迫复制有关类别详细信息的相同信息,只是将这些食品条目指定为单个实体而不是数组。

您需要考虑您提出的第一个解决方案,因为关联允许您在不同模型之间创建关系(例如,在“多对多”关系的情况下,数组到数组)。

此外,我建议您使用多态关联来简化类别模型,请参阅here