在Phoenix中处理多态关联的推荐方法似乎是添加一个包含对其他模式的引用的中间模式:
所以,如果我想用不同种类的动物创建模式,我会这样做:
defmodule Animal do
use Ecto.Model
schema "animals" do
belongs_to(:dog, Dog)
belongs_to(:cat, Cat)
belongs_to(:owner, PetOwner)
end
end
defmodule Dog do
use Ecto.Model
schema "dogs" do
end
end
defmodule Cat do
use Ecto.Model
schema "cats" do
end
end
defmodule PetOwner do
use Ecto.Model
schema "pet_owners" do
has_one(:pet, Animal)
end
end
Run Code Online (Sandbox Code Playgroud)
但我也可以使用PetOwner包含二进制字段和类型的模式:
defmodule Dog do
use Ecto.Model
schema "dogs" do
end
end
defmodule Cat do
use Ecto.Model
schema "cats" do
end
end
defmodule PetOwner do
use …Run Code Online (Sandbox Code Playgroud) 我从外部API中提取一些数据,并希望在本地缓存结果.我有一个class SearchTerm,我希望通过表格与几个不同的ActiveRecord类型相关联searchable_items.我很确定我的表格设置正确,但我的关联中的某些内容一定是错的.
class Foo < ActiveRecord::Base
has_many :search_terms, :as => :searchable, :through => :searchable_items
end
class Bar < ActiveRecord::Base
has_many :search_terms, :as => :searchable, :through => :searchable_items
end
class SearchTerm < ActiveRecord::Base
has_many :searchables, :through => :searchable_items
end
class SearchableItem < ActiveRecord::Base
belongs_to :search_term
belongs_to :searchable, :polymorphic => true
end
Run Code Online (Sandbox Code Playgroud)
我希望能够做类似的事情SearchTerm.find_by_term('SearchTerm').searchables(它会返回一个Foo和Bar对象的数组)然而,我得到了错误
Could not find the association :searchable_items in model SearchTerm
提前感谢您提供给我的任何见解!
我有一个产品,一个产品可以有很多图像.这是通过关联表.但是,我想要一个产品有一个主图像.
我知道这对模型中的方法很容易,但我希望它是一个关联,以便我可以使用在查询中预加载它include.
楷模:
class Product < ActiveRecord::Base
has_many :image_associations, :as => :imageable
has_many :images, :through => :image_associations
end
class ImageAssociation < ActiveRecord::Base
belongs_to :image
belongs_to :imageable, :polymorphic => true
end
class Image < ActiveRecord::Base
has_many :image_associations
end
Run Code Online (Sandbox Code Playgroud)
在ImageAssociation表中,有一个名为"feature"的布尔列,它将图像关联为"主要"图像.
我考虑过这样做的一种方法是main_image_id在products表中添加一列,然后添加到Image模型中:
belongs_to :image, :class => "Image", :foreign_key => "main_image_id"
Run Code Online (Sandbox Code Playgroud)
但是,如果主图像为零,则不允许任何回退到其他has_many图像 - 我希望加载关联.
这就是为什么我希望图像模型中的某些东西像:
has_one :image, :through => :images, :conditions => 'feature = true', :order => 'created_at DESC'
Run Code Online (Sandbox Code Playgroud)
但这给了我一个关联错误.
有没有什么方法可以编辑has_one,或者我是否真的需要运行rake任务将图像推送到每个main_image_id字段,然后为将来的产品添加验证以确保添加了主图像?
编辑:
我应该使用has_and_belongs_to_many协会吗?
我有几个类,每个都有评论:
class Movie < ActiveRecord::Base
has_many :comments, :as => :commentable
end
class Actor < ActiveRecord::Base
has_many :comments, :as => :commentable
end
class Comment < ActiveRecord::Base
belongs_to :commentable, :polymorphic => true
end
Run Code Online (Sandbox Code Playgroud)
如何为新电影评论创建表单?我补充道
resources :movies do
resources :comments
end
Run Code Online (Sandbox Code Playgroud)
到我的routes.rb,并尝试了new_movie_comment_path(@movie),但这给了我一个包含commentable_id和commentable_type的表单[我希望自动填充,而不是由用户直接输入].我也试过自己创建表单:
form_for [@movie, Comment.new] do |f|
f.text_field :text
f.submit
end
Run Code Online (Sandbox Code Playgroud)
(其中"text"是Comment表中的一个字段)但这也不起作用.
我真的不确定如何将评论与电影联系起来.例如,
c = Comment.create(:text => "This is a comment.", :commentable_id => 1, :commentable_type => "movie")
Run Code Online (Sandbox Code Playgroud)
似乎没有创建与ID为1的电影关联的注释.(Movie.find(1).comments返回一个空数组.)
我有一个多态关联,看起来像这样:
class Line < ActiveRecord::Base
belongs_to :item, :polymorphic => true
end
class Education < ActiveRecord::base
has_many :lines, :as => :item
end
class Work < ActiveRecord::base
has_many :lines, :as => :item
end
Run Code Online (Sandbox Code Playgroud)
我想要一种从父项创建新行的简单方法.因此,我可能正在编辑Work对象的视图,并希望有一个创建新Line对象的链接.通常,我会这样做:
<%= link_to "New Line", new_work_line_path(@work) %>
Run Code Online (Sandbox Code Playgroud)
帮助者将为此工作.但是,这需要我在控制器中检查Line属于哪个父级,从而破坏了多态性的目的(如果是这种情况,我可以使用两个引用).所以,我的问题是,我如何像普通的路径助手那样以多态方式工作?
使用Ruby on Rails,我如何实现多态has_many关系,其中所有者始终是已知的,但关联中的项目将具有某种多态(但同质)类型,由所有者中的列指定?例如,假设Producer类has_many产品但生产者实例可能实际上有许多自行车,或者冰棒或鞋带.我可以很容易地让每个产品类(自行车,冰棒等)belongs_to与生产者有关系但是给定生产者实例如果它们的类型不同(每个生产者实例),我如何获得产品集合?
Rails多态关联允许生产者属于许多产品,但我需要这种关系是另一种方式.例如:
class Bicycle < ActiveRecord::Base
belongs_to :producer
end
class Popsicle < ActiveRecord::Base
belongs_to :producer
end
class Producer < ActiveRecord::Base
has_many :products, :polymorphic_column => :type # last part is made-up...
end
Run Code Online (Sandbox Code Playgroud)
所以我的Producer表已经有一个"类型"列,它对应于某个产品类(例如Bicycle,Popsicle等),但是我怎样才能让Rails让我做类似的事情:
>> bike_producer.products
#=> [Bicycle@123, Bicycle@456, ...]
>> popsicle_producer.products
#=> [Popsicle@321, Popsicle@654, ...]
Run Code Online (Sandbox Code Playgroud)
对不起,如果这是显而易见的或常见的重复; 我很难轻易实现它.
我们在应用程序中使用多态关联.我们遇到了经典问题:我们遇到了无效的外键引用,我们无法创建外键约束,因为它是一个多态关联.
也就是说,我已经做了很多研究.我知道使用多态关联的缺点和好处.但我发现似乎是一个不错的解决方案:
这很好,因为你可以获得两全其美.我担心的是数据重复.我对postgresql没有足够深入的了解,无法完全理解这个解决方案的成本.
你的想法是什么?这个解决方案应该完全避免吗?或者这是一个很好的解决方案?
在我看来,唯一的选择是为每种关联类型创建一个外键.但是你会遇到验证只存在一个关联的问题.这是一个"挑选毒药"的情况.多态关联清楚地描述了意图,也使这种情况变得不可能.在我看来,这是最重要的.数据库外键约束是幕后功能,改变"意图"以使用数据库限制对我来说是错误的.这就是为什么我想使用上面的解决方案,假设它没有明显的"避免".
多态协会(PA)对于相对简单的数据库要求非常满意:让各种表在一个共享表中具有子记录.经典示例是具有注释记录的单个表,其适用于不同的不一定类似的实体.
在这个问题中, Mark做了很好的工作,展示了实现PA的三种常用方法.我想使用基表方法,Bill Karwin在同样优秀的答案中对此进行了更详细的描述.
一个具体的例子如下:

实体的主键引用基表中的相同键值,而注释表引用基表,因此可以观察到引用完整性.这里的关键部分是实体表的主键具有不同的域.它们是通过在基表中创建新记录并将其生成的密钥复制到实体的主键来生成的.
现在我的问题是:如果我想在具有生成自己的,相互重叠的主键的实体的现有数据库中引入具有引用完整性的PA,该怎么办?
到目前为止,我看到两个选项:
选项1:

每个实体都保留自己的主键,但也获得备用键.
喜欢:
不喜欢:
选项2:

每个实体在基表中都有自己的外键列.这看起来像Mark的多列方法.
喜欢:
不喜欢:
我倾向于选项1,可能在Base表中使用字段"EntityName"进行双向查找.哪个选项会更好.或者是另一种甚至更好的方法?
refactoring database-design polymorphic-associations sql-server-2008
我已经阅读了Bill Karwin关于单表继承的一些答案,并认为这种方法对我正在考虑的设置有好处:
Playlist
--------
id AUTO_INCREMENT
title
TeamPlaylist
------------
id REFERENCES Playlist.id
teamId REFERENCES Team.id
UserPlaylist
------------
id REFERENCES Playlist.id
userId REFERENCES User.id
PlaylistVideo
-------------
id
playlistId REFERENCES Playlist.id
videoId REFERENCES Video.id
Run Code Online (Sandbox Code Playgroud)
所有CASCADE选项都设置DELETE为在Playlist删除a时正常工作,但是,如果删除User或Team删除会发生什么?
即.如果User被删除,在行UserPlaylist会被删除,但被引用的行中Playlist,并PlaylistVideo仍将保留.我考虑过强制执行此操作,TRIGGER AFTER DELETE但无法知道删除请求是否因为Playlist已删除或删除而导致User.
在这种情况下,强制执行诚信的最佳方法是什么?
编辑(提供ERD)

mysql referential-integrity single-table-inheritance polymorphic-associations cascading-deletes
鉴于路线:
Example::Application.routes.draw do
concern :commentable do
resources :comments
end
resources :articles, concerns: :commentable
resources :forums do
resources :forum_topics, concerns: :commentable
end
end
Run Code Online (Sandbox Code Playgroud)
而型号:
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
end
Run Code Online (Sandbox Code Playgroud)
当我编辑或添加评论时,我需要回到"可评论"对象.但是我有以下问题:
1)redirect_to在comments_controller.rb根据父对象上的将是不同
2)关于观点的参考文献也会有所不同
= simple_form_for comment do |form|
Run Code Online (Sandbox Code Playgroud)
是否有实用的方法来共享此comment资源的视图和控制器?
ruby-on-rails polymorphic-associations ruby-on-rails-4 rails-activerecord
activerecord ×2
associations ×1
ecto ×1
elixir ×1
foreign-keys ×1
model ×1
mysql ×1
postgresql ×1
refactoring ×1
ruby ×1