多态关联 - rails
Polymorphic Associations - rails
我在理解 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
除了支持它所需的架构和语法外,没有太大区别。如果你有一些相对大量的 belongs_to :imageable 关系,它作为一个用例就开始有意义了。使用标准命名方法,他们会将表示多个 belongs_to 关联所需的 n 个字段减少为两个,"MODEL_able" 和一个引用目标模型 ID 的 ID。这有利于每个 belongs_to 模型有一个 MODEL_id。对他们来说,这是一场巨大的胜利是相当罕见的,但熟悉是一件好事。
在第二种情况下,您需要在图片 table.
中添加两个外键,即 employee_id 和 product_id
在第一种情况下 t.references :imageable, polymorphic: true
在您的图片迁移中会在图片中添加两个字段 table 即
t.integer :imageable_id
t.string :imageable_type
imagable_type
字段将是 class 的名称,您要将此模型关联到谁,imagable_id
将保存该记录的 ID。
例如
典型的图片行 table 看起来像
id | name | imagable_id | imagable_type |
1 | pic1 | 1 | Employee |
2 | pic2 | 3 | Product |
所以在这里,第一行的图片属于员工模型,其中包含 ID 为 1 的员工图片。第二行属于产品模型,其中包含 ID 为 3 的产品图片
第一种方法的优点是您以后可以将图片模型关联到任何其他模型,而无需向其添加外键。
只需添加行
has_many :pictures, as: :imageable
将设置关联。
假设您有这些模型:Post、想法、文章,并且您希望为所有三!
您可以使用三个表来进行评论,例如:
Post评论,
创意网,
文章评论
或您可以拥有一个通用评论模型并根据相关模型存储每个评论。
正如@Karan Purohit 提到的:)
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- 没有多态。我们使用了两个不同的 table 来做同样的事情。
2- 使用多态我们只创建了一个模型来存储第三个多态模型中两个或两个以上模型的图像。
这里我们需要第三个 table 中的两个库,一个用于 stroe model class name ,第二个用于 record id 。
我们可以取任意两列,但列名应该相同,如 imageable+id imageable+type
在这里我们可以使用 imageable 的任何名称,就像我们可以使用 poly_id poly_type 但我们必须确保我们在模型中使用的是什么。
如果我们使用 poly_id 和 poly_type 那么我们必须在 picture.rb 和 has_many 中使用 belogs_to :poly, polymorphic:true :图片,如:employee.rb 和 product.rb 中的 :poly
在两者中。
我在理解 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
除了支持它所需的架构和语法外,没有太大区别。如果你有一些相对大量的 belongs_to :imageable 关系,它作为一个用例就开始有意义了。使用标准命名方法,他们会将表示多个 belongs_to 关联所需的 n 个字段减少为两个,"MODEL_able" 和一个引用目标模型 ID 的 ID。这有利于每个 belongs_to 模型有一个 MODEL_id。对他们来说,这是一场巨大的胜利是相当罕见的,但熟悉是一件好事。
在第二种情况下,您需要在图片 table.
中添加两个外键,即 employee_id 和 product_id在第一种情况下 t.references :imageable, polymorphic: true
在您的图片迁移中会在图片中添加两个字段 table 即
t.integer :imageable_id
t.string :imageable_type
imagable_type
字段将是 class 的名称,您要将此模型关联到谁,imagable_id
将保存该记录的 ID。
例如
典型的图片行 table 看起来像
id | name | imagable_id | imagable_type |
1 | pic1 | 1 | Employee |
2 | pic2 | 3 | Product |
所以在这里,第一行的图片属于员工模型,其中包含 ID 为 1 的员工图片。第二行属于产品模型,其中包含 ID 为 3 的产品图片
第一种方法的优点是您以后可以将图片模型关联到任何其他模型,而无需向其添加外键。
只需添加行
has_many :pictures, as: :imageable
将设置关联。
假设您有这些模型:Post、想法、文章,并且您希望为所有三! 您可以使用三个表来进行评论,例如: Post评论, 创意网, 文章评论 或您可以拥有一个通用评论模型并根据相关模型存储每个评论。 正如@Karan Purohit 提到的:)
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- 没有多态。我们使用了两个不同的 table 来做同样的事情。
2- 使用多态我们只创建了一个模型来存储第三个多态模型中两个或两个以上模型的图像。
这里我们需要第三个 table 中的两个库,一个用于 stroe model class name ,第二个用于 record id 。
我们可以取任意两列,但列名应该相同,如 imageable+id imageable+type
在这里我们可以使用 imageable 的任何名称,就像我们可以使用 poly_id poly_type 但我们必须确保我们在模型中使用的是什么。
如果我们使用 poly_id 和 poly_type 那么我们必须在 picture.rb 和 has_many 中使用 belogs_to :poly, polymorphic:true :图片,如:employee.rb 和 product.rb 中的 :poly 在两者中。