我想要的是,使用Rails 3.1以某种方式构建它:
如果A
为b_id
设置了ID,则无法为c_id
设置ID。而且反过来也是如此。
我希望我能从数据库级别进行迁移(检查约束?)。这有点可能吗? 或者在带有验证的模型中更实惠?
我的环境:
答案 0 :(得分:2)
你可以通过多态关联实现这一点,虽然架构看起来不像你拥有的那样,你可以实现相同的目标,让A
项属于B
或者C
但永远不会两者兼得。
您可以在此处阅读更多内容:http://guides.rubyonrails.org/association_basics.html#polymorphic-associations
在该链接上提供的示例中,A
是他们的Picture
,而Employee
和Proudct
是您的B
和C
:
(从上面链接的来源复制):
class Picture < ActiveRecord::Base
belongs_to :imageable, :polymorphic => true
end
class Employee < ActiveRecord::Base
has_many :pictures, :as => :imageable
end
class Product < ActiveRecord::Base
has_many :pictures, :as => :imageable
end
答案 1 :(得分:0)
我肯定会为此编写验证 - 通过验证向用户提供良好的错误消息会更容易。我还想用数据库约束来支持它。看起来检查约束确实可以完成这项工作。
Rails不支持我可以找到的,所以你需要用raw sql创建表。您还需要将架构转储程序更改为:sql
,因为rails无法生成实际描述此内容的schema.rb
。
我写了这个迁移
class CreateFoos < ActiveRecord::Migration
def change
execute <<SQL
CREATE TABLE foos (
id INTEGER PRIMARY KEY,
x_id INTEGER,
y_id INTEGER,
constraint xorit check( (x_id OR y_id) AND NOT(x_id AND y_id))
)
SQL
end
end
然后在rails控制台
Foo.create(:x_id => 1, :y_id => 1) #=> SQLite3::ConstraintException
因为它可以创建一个既不设置x_id也不设置y_id的行。您可以通过更改约束
来更改此设置(x_id IS NOT NULL OR y_id IS NOT NULL ) AND (x_id IS NULL OR y_id IS NULL)
似乎对我有用