मैं अपने आवेदन में after_commit का उपयोग कर रहा हूं।एक विशेषता के लिए बाद_commit
मैं इसे तभी ट्रिगर करना चाहता हूं जब मेरे मॉडल में कोई विशेष फ़ील्ड अपडेट हो। कोई जानता है कि उसे कैसे करना है?
मैं अपने आवेदन में after_commit का उपयोग कर रहा हूं।एक विशेषता के लिए बाद_commit
मैं इसे तभी ट्रिगर करना चाहता हूं जब मेरे मॉडल में कोई विशेष फ़ील्ड अपडेट हो। कोई जानता है कि उसे कैसे करना है?
ऐसा लगता है जैसे आप conditional callback की तरह कुछ चाहते हैं। आप कुछ कोड मैं सही दिशा तथापि में आप इशारा किया जा सकता था तैनात किया था, तो मुझे लगता है कि आप कुछ इस तरह का उपयोग करना चाहते हैं: after_commit
का इन
after_commit :callback,
:if => Proc.new { |record| record.field_modified? }
मुझे नहीं लगता कि आप यह कर सकते हैं के बाद लेन-देन मेरी रेल कंसोल में Rails Transactions
प्रतिबद्ध है उदाहरण के लिए
> record = MyModel.find(1)
=> #<MyModel id: 1, label: "test", created_at: "2011-08-19 22:57:54", updated_at: "2011-08-19 22:57:54">
> record.label = "Changing text"
=> "Changing text"
> record.label_changed?
=> true
> record.save
=> true
> record.label_changed?
=> false
आप इसलिए after_commit कहा जाता है पर :if
स्थिति का उपयोग करने में सक्षम नहीं होंगे क्योंकि विशेषता को सहेजे जाने के रूप में अब और परिवर्तित नहीं किया जाएगा। रिकॉर्ड को सहेजने से पहले आपको यह ट्रैक करने की आवश्यकता हो सकती है कि आप जिस क्षेत्र के बाद हैं, changed?
किसी अन्य कॉलबैक में है?
इस पुराने प्रश्न का उत्तर देना है क्योंकि यह अभी भी खोज परिणामों में पॉप अप होता है
आप previous_changes विधि है जो प्रारूप के हैश returnes उपयोग कर सकते हैं:
{ "changed_attribute" => [ "पुराने मूल्य "," नया मान "]}
यह क्या changes था, जब तक रिकॉर्ड वास्तव में सहेजा जाता है (active_record/attribute_methods/dirty.rb से) है:
def save(*) #:nodoc:
if status = super
@previously_changed = changes
@changed_attributes.clear
# .... whatever goes here
तो आपके मामले में आप previous_changes.key? "your_attribute"
या कि
पुराने सवाल की तरह कुछ के लिए जाँच कर सकते हैं, लेकिन यह एक तरीका है कि मैं मिल गया है (बंद paukul's answer काम) कि after_commit कॉलबैक के साथ काम हो सकता है। कम से कम, मूल्य आईआरबी में पोस्ट-प्रतिबद्ध बने रहते हैं।
after_commit :callback,
if: proc { |record|
record.previous_changes.key?(:attribute) &&
record.previous_changes[:attribute].first != record.previous_changes[:attribute].last
}
[प्रलेखन] (http://apidock.com/rails/ActiveModel/Dirty/previous_changes) के आधार पर, मुझे लगता है कि 'कुंजी' को कॉल किया जाना चाहिए: 'record.previous_changes.keys.include? (: विशेषता)'। इस बदलाव के साथ, यह मेरे लिए काम करता है। – milkfarm
'record.previous_changes.key? (: विशेषता)' पर्याप्त शर्त है, क्योंकि पहले और अंतिम मान हमेशा बराबर नहीं होते हैं। –
@jamesdevar सही है, लेकिन यह समाधान विफल हो सकता है यदि आपका मॉडल लेनदेन के दौरान एक से अधिक बार सहेजा जाता है। यहां समस्या का प्रदर्शन करने के लिए एक नमूना रेल परियोजना https://github.com/ccmcbeck/after-commit है और इसे ठीक करने का मेरा समाधान यहां दिया गया है। –
मणि ArTransactionChanges का उपयोग करें। previous_changes
रेल 4.0.x में मेरे लिए काम नहीं कर रहा
उपयोग:
class User < ActiveRecord::Base
include ArTransactionChanges
after_commit :print_transaction_changes
def print_transaction_changes
transaction_changed_attributes.each do |name, old_value|
puts "attribute #{name}: #{old_value.inspect} -> #{send(name).inspect}"
end
end
end
यह एक बहुत ही पुरानी समस्या है, लेकिन उसे स्वीकार previous_changes
समाधान सिर्फ पर्याप्त मजबूत नहीं है। ActiveRecord
लेन-देन में, कई कारण हैं कि आप मॉडल को दो बार क्यों बचा सकते हैं। previous_changes
केवल अंतिम save
के परिणाम को दर्शाता है।इस उदाहरण
class Test < ActiveRecord::Base
after_commit: :after_commit_test
def :after_commit_test
puts previous_changes.inspect
end
end
test = Test.create(number: 1, title: "1")
test = Test.find(test.id) # to initialize a fresh object
test.transaction do
test.update(number: 2)
test.update(title: "2")
end
जो आउटपुट पर विचार करें:
{"title"=>["1", "2"], "updated_at"=>[...]}
लेकिन, क्या आप की जरूरत है:
{"title"=>["1", "2"], "number"=>[1, 2], "updated_at"=>[...]}
तो, मेरे समाधान यह है:
module TrackSavedChanges
extend ActiveSupport::Concern
included do
# expose the details if consumer wants to do more
attr_reader :saved_changes_history, :saved_changes_unfiltered
after_initialize :reset_saved_changes
after_save :track_saved_changes
end
# on initalize, but useful for fine grain control
def reset_saved_changes
@saved_changes_unfiltered = {}
@saved_changes_history = []
end
# filter out any changes that result in the original value
def saved_changes
@saved_changes_unfiltered.reject { |k,v| v[0] == v[1] }
end
private
# on save
def track_saved_changes
# maintain an array of ActiveModel::Dirty.changes
@saved_changes_history << changes.dup
# accumulate the most recent changes
@saved_changes_history.last.each_pair { |k, v| track_saved_change k, v }
end
# v is an an array of [prev, current]
def track_saved_change(k, v)
if @saved_changes_unfiltered.key? k
@saved_changes_unfiltered[k][1] = track_saved_value v[1]
else
@saved_changes_unfiltered[k] = v.dup
end
end
# type safe dup inspred by http://stackoverflow.com/a/20955038
def track_saved_value(v)
begin
v.dup
rescue TypeError
v
end
end
end
आप जो यहां आज़मा सकते हैं: https://github.com/ccmcbeck/after-commit
field_modified है? एक पूर्व-निर्मित विधि या क्या यह एक तरीका है जिसे मुझे फ़ील्ड मान की जांच करने के लिए लिखना होगा? मूल रूप से मैं अपनी सभी नियुक्ति रेटिंग के आधार पर उपयोगकर्ता की रेटिंग को पुन: गणना और सहेजने का प्रयास कर रहा हूं। एक अपॉइंटमेंट के लिए रेटिंग को बनाया जाने के बाद जोड़ा जा सकता है, इसलिए मैं जानना चाहता हूं कि रेटिंग फ़ील्ड को अपडेट किया गया था यहां कुछ कोड है जो मैं क्लास अपॉइंटमेंट
alik
नहीं फ़ील्ड मान की जाँच करें। –