【问题标题】:How to deal with xor conditions, rails, foreign keys and a sqlite database?如何处理异或条件、轨道、外键和 sqlite 数据库?
【发布时间】:2012-01-29 05:31:07
【问题描述】:

我想要的是,用 Rails 3.1 以某种方式构建它:

如果Ab_id 设置了一个ID,则应该不可能为c_id 设置一个ID。反之亦然。

我希望我可以在数据库级别进行迁移(检查约束?)。这有可能吗? 还是在带有验证的模型中执行此操作更实惠?

我的环境:

  • Ruby 1.9.3
  • Rails 3.1.3
  • SQLite 3.7.3

【问题讨论】:

    标签: ruby-on-rails sqlite database-design xor


    【解决方案1】:

    您可以通过多态关联来实现这一点,尽管架构看起来与您拥有的不完全相同,但您可以实现相同的目标,让项目 A 属于 BC 但是永远不要两者兼而有之。

    您可以在这里阅读更多内容:http://guides.rubyonrails.org/association_basics.html#polymorphic-associations

    在该链接给出的示例中,A 是他们的 PictureEmployeeProudct 是您的 BC

    (从上面链接的来源复制):

    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
    

    【讨论】:

    • 感谢您的回答!结合@Frederick 的回答,我将得到一个完整的解决方案。
    • 我更同意@mynameiscoffey 的回答。表A 中只有一列外键,因此表A 中有imageable_idimageable_type
    【解决方案2】:

    我肯定会为此编写验证 - 从验证中向用户提供好的错误消息更容易。我还想用数据库约束来备份它。看起来检查约束确实可以完成这项工作。

    Rails 不支持我可以找到的这一点,因此您需要使用原始 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)
    

    似乎对我有用

    【讨论】:

    • 感谢您的回答!结合@mynameiscoffey 的回答,我将得到我的问题的完整解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多