簡體   English   中英

如何在驗證中訪問關聯的表屬性,然后將它們保存在 Rails 上的 Ruby 中

[英]How to access associated table attributes in validation before they are saved in Ruby on Rails

如果某個屬性設置為假,我希望能夠跳過驗證,比如狀態,問題是這個 model 有許多嵌套屬性,如果狀態為假,他們也需要跳過驗證。

這種植入的目的是,如果有人想保存表單條目的草稿,無論出於何種原因,讓它通過驗證可能會阻止他們保存它,這是不可取的行為,只需要驗證公開的條目通過將狀態設置為真。

下面的例子

位於文章中的屬性狀態

model Article
  has_many :sub_articles
  accepts_nested_attributes_for :sub_articles, :allow_destroy => true

  validate_presence_of :body, :unless => Proc.new{|article| !article.status }

model SubArticle
  belongs_to :article
  has_many :foos
  accepts_nested_attributes_for :foos, :allow_destroy => true    

  validate_presence_of :body, :unless => Proc.new{|sub_article| !sub_article.article.status }

model Foo
  belongs_to :sub_article

  validate_presence_of :body, :unless => Proc.new{|foo| !foo.sub_article.article.status }

Article 的驗證跳過將起作用,但對於 SubArticle 或 Foo 無效,因為它們尚未保存並且未設置 ID,因此無法像示例中那樣遍歷關聯。

是否可以在驗證時訪問關聯的表屬性?

任何幫助將不勝感激。

- - - 更新 - - -

SubArticle 和 Foo 驗證失敗的原因是因為

nil:NilClass 的未定義方法“狀態”

這是預期的,因為在驗證時 article_id 或 sub_article_id 仍然為零,我已經通過這樣做確認了這一點

model SubArticle
  belongs_to :article
  has_many :foos

  validate_presence_of :body, :unless => Proc.new{|sub_article| !sub_article.article.check_attributes }

def check_attributes
  pp self
end

女巫給

#<SubArticle id: nil, body: "", article_id: nil, created_at: nil, updated_at: nil >

------更新2----------

我忘記了重要的細節,模型的所有數據都是使用嵌套形式一次輸入的,所以在創建時,所有模型上的所有條目都只在 memory 中,修復示例代碼以便更明顯。

這是可能的,但您需要使用=>而不是= 像這樣:

validate_presence_of :body, :unless => Proc.new{|article| !article.status }

有關條件驗證的更多信息,請查看: http://guides.rubyonrails.org/active_record_validations_callbacks.html#conditional-validation

有條件地驗證 ID 怎么樣?

model Article
  has_many :sub_articles

  validate_presence_of :body, :unless => Proc.new{|article| !article.status }

    model SubArticle
      belongs_to :article
      has_many :foos

      validate_presence_of :body, :unless => Proc.new{|sub_article| !sub_article.article_id}

model Foo
  belongs_to :sub_article

  validate_presence_of :body, :unless => Proc.new{|foo| !foo.sub_article_id }

不確定這是否可行,但您實際上只是在父 model 已保存並因此具有 ID 時才運行驗證。 雖然不適用於更新。 也許這與您的原始代碼之間的混合可以進行更新?

我已經讓它工作了,雖然 hack-ish,解決了不能遍歷關聯的問題,因為 id 是 nil 通過使用:inverse_of

model Article
  has_many :sub_articles, :inverse_of => :article

  validate_presence_of :body, :unless => Proc.new{|article| !article.status }

model SubArticle
  belongs_to :article, :inverse_of => :sub_articles
  has_many :foos, :inverse_of => :foo

  validate_presence_of :body, :unless => Proc.new{|sub_article| !sub_article.article.status }

model Foo
  belongs_to :sub_article, :inverse_of => :foos

  validate_presence_of :body, :unless => Proc.new{|foo| !foo.sub_article.article.status }

這將使所有層中正在檢查的實例都可以訪問狀態屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM