使用严格属于rails 5

时间:2017-02-13 04:18:12

标签: ruby-on-rails ruby-on-rails-5

假设我们有以下模型:

class A < AR
    has_many :bs

    accepts_nested_attributes_for :bs
end

class B < AR
    belongs_to :a
end

我们以这种方式创建具有嵌套表单的新A对象:

class AsController < AC
    def create
        a = A.create(a_params)
    end

    ...
    def a_params
        params.require(:a).permit(bs_attributes: [...])
    end
end

这会产生类似b.a must be exists的错误。这意味着b.a_id不能为nil或a必须先创建。

所有人都说,belongs_to关联的解决方案是optional: true

但是当关联非常严格且b.a永远不会为零时会发生什么?

一个好的解决方案是optional: true并在B上添加验证规则吗?

1 个答案:

答案 0 :(得分:0)

我们经常想验证具有belongs_to关系的内容是否设置了该列。

例如,如果我们有属于讨论的帖子,那么可能希望确保每个帖子都属于讨论并且其discussion_id已设置。验证这是rails 5中的默认行为。

在Rails 4中,我们不得不添加类似的东西......

class Post
  belongs_to :discussion
  validates :discussion_id, presence: true
end

但是,在Rails 5中设置belongs_to :discussion, optional: true将取消该验证。如果我想允许存在与讨论无关的帖子,我只会这样做。

如果您希望示例中的A has_many :bs关系严格,请不要添加optional: true,Rails 5将为您验证。

参考:http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

如果您想同时创建A和新B,那么您将要遵循http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html中列出的模式

params = { a: {
  name: 'A new A!', bs_attributes: [
    { title: 'Something new b' },
    { title: 'Something else new b' }
  ]
}}


class AsController < AC
  def create
    a = A.create(a_params)
  end

    ...
  def a_params
    params.require(:a).permit(:name, bs_attributes: [...])
  end
end


a.bs.length # => 2
a.bs.first.title # => 'Something new b'
a.bs.second.title # => 'Something else new b'