【问题标题】:Polymorphic Associations - rails多态关联 - rails
【发布时间】:2016-09-02 05:07:58
【问题描述】:

我在理解 Rails 中的多态关联时遇到了一些麻烦。 怎么样

class Picture < ApplicationRecord
  belongs_to :imageable, polymorphic: true
end

class Employee < ApplicationRecord
  has_many :pictures, as: :imageable
end

class Product < ApplicationRecord
  has_many :pictures, as: :imageable
end

不同于

class Picture < ApplicationRecord
  belongs_to :employee
  belongs_to :product
end

class Employee < ApplicationRecord
  has_many :pictures
end

class Product < ApplicationRecord
  has_many :pictures
end

【问题讨论】:

    标签: ruby-on-rails activerecord polymorphic-associations


    【解决方案1】:

    在第二种情况下,您需要在图片表中添加两个外键,即employee_id 和product_id。

    在第一种情况下t.references :imageable, polymorphic: true 在您的图片迁移中将在图片表中添加两个字段,即

    t.integer :imageable_id
    t.string  :imageable_type
    

    imagable_type 字段将是您将此模型关联到的类的名称,imagable_id 将保存该记录的 ID。

    例如,

    图片表的典型行如下所示

    id | name | imagable_id | imagable_type |
    
    1  | pic1 | 1           | Employee      |
    2  | pic2 | 3           | Product       |
    

    所以在这里,第一行的图片将属于持有 id 为 1 的员工图片的员工模型。第二行将属于持有 id 为 3 的产品图片的产品模型

    第一种方法的优点是您可以在将来将图片模型关联到任何其他模型,而无需为其添加外键。

    只需添加一行

    has_many :pictures, as: :imageable
    

    将设置关联。

    【讨论】:

      【解决方案2】:

      除了支持它所需的架构和语法外,没有太大区别。如果您有一些相对大量的 belongs_to :imageable 关系,它作为一个用例将开始有意义。使用标准命名方法,他们将表示多个 belongs_to 关联所需的 n 个字段减少为两个,“MODEL_able”和一个引用目标模型 id 的 id。这有利于为每个 belongs_to 模型设置一个 MODEL_id。对于他们来说,获得巨大的胜利是相当罕见的,但熟悉起来却是一件好事。

      【讨论】:

        【解决方案3】:
        Without Polymorphic
        20160902065429_create_employee_images
        class CreateEmployeeImages < ActiveRecord::Migration[5.0]
            def change
                create_table :employee_images do |t|
                    t.integer :employee_id
                    t.string :image
        
                    t.timestamps
                end
            end
        end
        20160902065445_create_product_images
        class CreateProductImages < ActiveRecord::Migration[5.0]
            def change
                create_table :product_images do |t|
                    t.integer :product_id
                    t.string :image
                    t.timestamps
                end
            end
        end
        
        app/model/employee.rb
        class Employee < ApplicationRecord
            has_many :employee_images
        end
        
        app/model/product.rb
        class Product < ApplicationRecord
            has_many :pictures, as: :imageable
        end
        
        app/model/employee_image.rb
        class EmployeeImage < ApplicationRecord
            belongs_to :employee
        end
        
        app/model/product_image.rb
        class ProductImage < ApplicationRecord
            belogs_to :product
        end
        
        With Polymorphic
        
        db/migrate/20160902063459_create_products.rb
        class CreateProducts < ActiveRecord::Migration[5.0]
            def change
                create_table :products do |t|
                    t.string :name
                    t.timestamps
                end
            end
        end
        
        db/migrate/20160902063513_create_employees.rb
        class CreateEmployees < ActiveRecord::Migration[5.0]
            def change
                create_table :employees do |t|
                    t.string :name
                    t.timestamps
                end
            end
        end
        
        db/migrate/20160902063602_create_pictures.rb
        class CreatePictures < ActiveRecord::Migration[5.0]
            def change
                create_table :pictures do |t|
                    t.string :picture
                    t.integer :imageable_id
                    t.string :imageable_type
                    t.string :image
        
                    t.timestamps
                end
            end
        end
        
        app/model/employee.rb
        class Employee < ApplicationRecord
            has_many :pictures, as: :imageable
        end
        
        app/model/picture.rb
        class Picture < ApplicationRecord
            belongs_to :imageable, polymorphic: true
        end
        
        app/model/product.rb
        class Product < ApplicationRecord
            has_many :pictures, as: :imageable
        end
        

        1- 没有多态性。我们使用了两个不同的表来做同样的事情。 2- 对于多态,我们只创建了一个模型来将两个或两个以上模型的图像存储在第三个多态模型中。
        这里我们需要第三个表中的两个库,一个用于 stroe 模型类名称,第二个用于记录 id。 我们可以取任意两列,但列名应与 imageable+id imageable+type 相同 在这里我们可以使用 imageable 的任何名称,就像我们可以使用 poly_id poly_type 一样,但我们必须确保我们在模型中使用的是什么。

        如果我们使用 poly_id 和 poly_type 那么我们必须在 picture.rb 和 has_many :pictures 中使用 belogs_to :poly, polymorphic:true, as: 在employee.rb 和 product.rb 中都使用:poly 在两者中。

        【讨论】:

          【解决方案4】:

          假设您有这些模型:Post、Idea、Article,并且您希望对所有三个模型都有评论! 您可以为 cmets 提供三个表,例如: 发表评论, IdeaCommnet, 文章评论 您可以拥有一个通用评论模型并根据其相关模型存储每条评论。 正如@Karan Purohit 提到的:)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-03-23
            • 2019-03-14
            • 2016-04-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多