【问题标题】:Does Rails has a way to validate if the foreign key value exists in an optional relationship?Rails 是否有办法验证外键值是否存在于可选关系中?
【发布时间】:2017-09-26 01:17:59
【问题描述】:

我使用的是 Rails 5.1.3 版。

Rails 是否有办法验证外键值是否存在于可选关系中?

我有下一个模型:

class Post < ApplicationRecord

  belongs_to :category, optional: true
  validates :category, presence: true, allow_nil: true

end

这是迁移:

class CreatePosts < ActiveRecord::Migration[5.1]
  def change
    create_table :posts do |t|
      t.string :name, limit: 100
      t.references :category, foreign_key: true, null: true

      t.timestamps
    end
  end
end

这些是案例:

# Case 1
p1 = Post.new({}) 
p1.save #Working as I expected ... record Inserted

# Case 2
p2 = Post.new({category_id: 3})  # A category with id 3 exists 
p2.save #Working as I expected ... record Inserted

# Case 3
p3 = Post.new({category_id: 30})  # A category with id 30 does not exists.  
p3.save # Not working as I expected 

在案例 3 中,我期待 Active Record 验证错误,例如 This Category does not exist 但我得到 一条 SQL 消息:

INSERT INTO "posts" ("category_id", "created_at", "updated_at") VALUES (?, ?, ?)  [["category_id", 10], ["created_at", "2017-09-26 00:59:47.645185"], ["updated_at", "2017-09-26 00:59:47.645185"]]

ActiveRecord::InvalidForeignKey: SQLite3::ConstraintException: FOREIGN KEY constraint failed: INSERT INTO "posts" ("category_id", "created_at", "updated_at") VALUES (?, ?, ?)

【问题讨论】:

    标签: ruby-on-rails-5.1


    【解决方案1】:

    数据库正在强制执行外键完整性,这意味着它不允许您将事物与另一个不存在的事物相关联。这是预期的行为。

    如果您想在关联不存在的情况下执行某些操作,则应在尝试创建关联之前先进行查找。

    您为外键关系设置的可选验证仅表示关系不是必需的。换句话说,您可以创建与类别无关的帖子。但是,这并不意味着如果您尝试与不存在的类别建立关联,数据库会很高兴。不管你有没有提供关联,Rails 都很酷,但是一旦它试图做一些违反数据库设置的规则的事情,那么数据库完全有权投诉!

    【讨论】:

      【解决方案2】:

      这可能会有所帮助:

      validates :category,
        presence: true,
        if: -> { category_id.present? }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-02-21
        • 1970-01-01
        • 2021-10-01
        • 2012-01-27
        • 2021-06-21
        相关资源
        最近更新 更多