我在了解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
答案 0 :(得分:3)
除了支持它所需的模式和语法之外没有太大区别。如果你有一些相对大量的belongs_to:imageable关系,它将作为一个用例开始有意义。使用标准命名方法,它们将n个表示多个belongs_to关联所需的字段减少为两个,“MODEL_able”和一个引用目标模型id的id。这有利于为每个belongs_to模型设置MODEL_id。他们很难成为一个巨大的胜利,但是熟悉它是一件好事。
答案 1 :(得分:3)
在第二种情况下,您需要在图片表中添加两个外键,即employee_id和product_id。
在图片迁移的第一种情况t.references :imageable, polymorphic: true
中,将在图片表中添加两个字段,即
t.integer :imageable_id
t.string :imageable_type
imagable_type
字段将是与您将此模型关联到的类的名称,而imagable_id
将保存该记录的ID。
e.g,
图片表的典型行看起来像
id | name | imagable_id | imagable_type |
1 | pic1 | 1 | Employee |
2 | pic2 | 3 | Product |
所以这里,第一行图片属于员工模型,持有ID为1的员工图片。第二行属于产品型号,持有ID为3的产品图片
第一种方法的优点是您可以在以后将图片模型与任何其他模型相关联,而无需添加外键。
只需添加一行
即可has_many :pictures, as: :imageable
将设置关联。
答案 2 :(得分:1)
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-对于多态,我们只创建了一个模型来存储第三个多态模型中两个或两个以上模型的图像。
这里我们在第三个表中需要两个coulms,一个用于stroe模型类名,第二个用于记录id。
我们可以使用任意两列,但列名应该与imageable + id imageable + type相同
在这里我们可以使用任何可成像的名称,就像我们可以使用poly_id poly_type但我们必须确保我们在模型中使用的是什么。
如果我们使用poly_id和poly_type,那么我们必须在picture.rb和has_many:pictures中使用belogs_to:poly,polymorphic:true,如::employee.rb和product.rb中的poly 在两者中。
答案 3 :(得分:0)
想象你有这些模型:帖子,想法,文章,你想拥有所有三个的评论模型! 你可以有三个表来评论: 发表评论, IdeaCommnet, ArticleComment 或 您可以拥有一般评论模型,并根据其相关模型存储每条评论。 正如@Karan Purohit所说:)