2013-05-24 7 views
11

मुझे इन दो कक्षाएं मिल गई हैं।रेल: यदि has_many संबंध बदल गया है

class Article < ActiveRecord::Base 
    attr_accessible :body, :issue, :name, :page, :image, :video, :brand_ids 
    has_many :publications 
    has_many :docs, :through => :publications 
end 

class Doc < ActiveRecord::Base 
    attr_accessible :issue_id, :cover_id, :message, :article_ids, :user_id, :created_at, :updated_at, :issue_code, :title, :template_id 
    has_many :publications, dependent: :destroy 
    has_many :articles, :through => :publications, :order => 'publications.position' 
    has_many :edits, dependent: :destroy 
    accepts_nested_attributes_for :articles, allow_destroy: false 
end 

मैं एक सशर्त बयान कैसे लिख सकता हूँ अगर @doc.articles@doc को अद्यतन करने के बाद बदल गया है को देखने के लिए चाहते हैं?

if @doc.articles.changed? 
    ... 
end 

उपर्युक्त मुझे एक त्रुटि देता है। मुझे सही वाक्यविन्यास नहीं मिल रहा है।

उत्तर

16

आपको प्रत्येक को जांचना होगा। .changed? केवल एक रिकॉर्ड पर काम करता है। आप कुछ इस तरह कर सकता है आप कम से कम एक बदलाव के लिए पूरे संघ जांच करने की आवश्यकता है, तो:

if @doc.articles.find_index {|a| a.changed?} then... 

या आप Enumerable#any? उपयोग कर सकते हैं:

if @doc.articles.any? {|a| a.changed?} then... 
+0

बिल्कुल सही! धन्यवाद। –

+0

उस मामले के बारे में क्या है जहां सूची में has_many जोड़ा गया है? यह एक बदलाव है, लेकिन क्या यह इस तरह से पता लगाया जाएगा? – aaaronic

+3

क्या यह पता लगाने का कोई तरीका है कि @ person.task_ids_changed ?. मैं यह जानना चाहता हूं कि _ids सरणी बदलती है या नहीं। – Stone

2

मैं Enumerable # किसी भी पाया? एक मध्यवर्ती निम्नलिखित तरीके से आईडी द्वारा रिवर्स छंटाई के कदम के साथ उपयोगी:

@doc.articles.sort { |a, b| b.id <=> a.id }.any?(&:changed?) 

उस तरह कदम में मदद करता है किसी भी? पुराने लौटने के बजाय, पुराने आलेख के माध्यम से लूपिंग के बजाय कोई परिवर्तन किया गया था या नहीं।

उदा। मेरे मामले में मैं एक has_many :event_responders संबंध था और संग्रह के लिए एक नया EventResponder जोड़ने के बाद, मैं पुष्टि ऊपर निम्नलिखित तरीके से काम कर रहे हैं: एक मध्यवर्ती तरह

2.2.1 :019 > ep.event_responders.any? { |a| puts a.changes; a.changed? } 
{} 
{} 
{} 
{} 
{"created_at"=>[Thu, 03 Sep 2015 08:25:59 UTC +00:00, Thu, 03 Sep 2015 08:25:59 UTC +00:00], "updated_at"=>[Thu, 03 Sep 2015 08:25:59 UTC +00:00, Thu, 03 Sep 2015 08:25:59 UTC +00:00]} 
=> true 

का उपयोग कर एक का उपयोग करते हुए बिना

इंटरमीडिएट सॉर्ट

2.2.1 :020 > ep.event_responders.sort { |a, b| b.id <=> a.id }.any? { |a| puts a.changes; a.changed? } 
{"created_at"=>[Thu, 03 Sep 2015 08:25:59 UTC +00:00, Thu, 03 Sep 2015 08:25:59 UTC +00:00], "updated_at"=>[Thu, 03 Sep 2015 08:25:59 UTC +00:00, Thu, 03 Sep 2015 08:25:59 UTC +00:00]} 
=> true 

धन्यवाद।

7

देर है, लेकिन अन्य लोग हैं, जो एक ऐसी ही समाधान के लिए देख रहे हैं, तो आप इस रास्ते पर रिश्ता (भी has_and_belongs_to_many) में परिवर्तन का पता लगाने कर सकते हैं के लिए यह है कि:

class Article < ActiveRecord::Base 
    attr_accessible :body, :issue, :name, :page, :image, :video, :brand_ids 
    has_many :publications 
    has_many :docs, :through => :publications 
end 

class Doc < ActiveRecord::Base 
    attr_accessible :issue_id, :cover_id, :message, :article_ids, :user_id, :created_at, :updated_at, :issue_code, :title, :template_id 
    has_many :publications, dependent: :destroy 
    has_many :articles, :through => :publications, :order => 'publications.position' 
    has_many :edits, dependent: :destroy 
    accepts_nested_attributes_for :articles, allow_destroy: false 

    after_initialize :initialize_article_changes_safe 

    after_save :change_articles 
    after_save :initialize_article_changes 

    before_add_for_articles << ->(method,owner,change) { owner.send(:on_add_article, change) } 
    before_remove_for_articles << ->(method,owner,change) { owner.send(:on_remove_article, change) } 

    def articles_changed? 
    @article_changes[:removed].present? or @article_changes[:added].present? 
    end 

    private 

    def on_add_article(article) 
    initialize_article_changes_safe 
    @article_changes[:added] << article.id 
    end 

    def on_remove_article(article) 
    initialize_article_changes_safe 
    @article_changes[:removed] << article.id 
    end 

    def initialize_article_changes 
    @article_changes = {added: [], removed: []} 
    end 

    def initialize_article_changes_safe 
    @article_changes = {added: [], removed: []} if @article_changes.nil? 
    end 

    def unchanged_article_ids 
    self.article_ids - @article_changes[:added] - @article_changes[:removed] 
    end 

    def change_articles 
    do_stuff if self.articles_changed? 
    do_stuff_for_added_articles unless @article_changes[:added].nil? 
    do_stuff_for_removed_articles unless @article_changes[:removed].nil? 
    end 
end 

दो हुक before_add_for_NAME-OF-RELATION और before_remove_for_NAME-OF-RELATION ट्रिगर कर रहे हैं एक संबंध जोड़ने या हटाने के दौरान। ट्रिगर किए गए फ़ंक्शंस (आप नाम से किसी फ़ंक्शन को लिंक नहीं कर सकते हैं, आपको इसे लैम्ब्डा द्वारा करना है) @articel_changes हैश में जोड़े गए/हटाए गए संबंध आइटमों की आईडी जोड़ें। जब मॉडल सहेजा जाता है, तो आप change_articles फ़ंक्शन में ऑब्जेक्ट्स को अपने आईडी द्वारा संभाल सकते हैं। इसके बाद, @articel_changes हैश साफ़ कर दिया जाएगा।

संबंधित मुद्दे