রেকর্ড সবেমাত্র তৈরি করা হয়েছে বা পরে সংরক্ষণে আপডেট করা হয়েছে কীভাবে তা নির্ধারণ করবেন


98

# নতুন_রেকার্ড? কোনও রেকর্ড সংরক্ষণ করা হয়েছে কিনা তা ফাংশন নির্ধারণ করে। তবে এটি সর্বদা after_saveহুকের মধ্যে মিথ্যা । রেকর্ডটি নতুনভাবে নির্মিত রেকর্ড বা আপডেট থেকে কোনও পুরানো কিনা তা নির্ধারণ করার কোনও উপায় আছে কি?

আমি আশা করছি যে অন্য কোনও কলব্যাক ব্যবহার না করা যেমন before_createমডেলটিতে একটি পতাকা সেট করতে বা ডিবিতে অন্য কোয়েরি প্রয়োজন।

কোন পরামর্শ প্রশংসা করা হয়।

সম্পাদনা করুন: এটি after_saveহুকটিতে নির্ধারণ করা দরকার এবং আমার নির্দিষ্ট ব্যবহারের ক্ষেত্রে কোনও updated_atবা updated_onটাইমস্ট্যাম্প নেই


4
হুম হয়ত আগে_সেভ করে একটা পরম পাস? কেবল উচ্চস্বরে চিন্তা করা
ট্রিপ

উত্তর:


170

আমি একটি after_saveকলব্যাকের জন্য এটি ব্যবহার করার সন্ধান করছিলাম ।

একটি সহজ সমাধানটি হ'ল id_changed?(যেহেতু এটি চালু হবে না update) বা created_at_changed?টাইমস্ট্যাম্প কলামগুলি উপস্থিত থাকলেও ।

আপডেট: @ মিটসির উল্লেখ হিসাবে, যদি এই চেকটি কলব্যাকের বাইরে প্রয়োজন হয় তবে ব্যবহার করুন id_previously_changed?দস্তাবেজগুলি দেখুন ।


4
মাধ্যমে ActiveModel :: ডার্টি
chaserx

6
একটি পরের_আর আপডেট এবং একটি উত্তরোত্তর তৈরির সাথে পার্থক্য করা ভাল। কলব্যাকগুলি এমন একটি সাধারণ পদ্ধতি ভাগ করতে পারে যা এটি তৈরি বা আপডেট হয় কিনা তা বোঝাতে একটি যুক্তি লাগে।
matthuhiggins

4
এটি সম্ভবত পরিবর্তিত হয়েছে। কমপক্ষে 4 রেলগুলিতে, পরের_সেভ কলব্যাক পরবর্তী_ক্রেট পরে বা পরে_প্লেড কলব্যাকের পরে চলে ( গাইডস.আরবিওনরইলস.আরেক্টিভ_রেকর্ড_ক্যালব্যাকস html দেখুন )।
চিহ্নিত করুন

4
এই ক্ষেত্রগুলির কোনওটিরও বাইরে কাজ করা হয় না after_save
ফতুহোকু

4
id_changed?রেকর্ডটি সংরক্ষণ করার পরে মিথ্যা হবে (হুকের বাইরে অন্তত)। id_previously_changed?
সেক্ষেত্রে

31

আমি জানি যে এখানে কোনও রেলের যাদু নেই, আপনাকে এটি নিজেই করতে হবে। আপনি ভার্চুয়াল বৈশিষ্ট্য ব্যবহার করে এটি পরিষ্কার করতে পারেন ...

আপনার মডেল শ্রেণিতে:

def before_save
  @was_a_new_record = new_record?
  return true
end

def after_save
  if @was_a_new_record
    ...
  end
end

27

তবুও অন্য কোনো বিকল্প, যারা জন্য কি করতে একটি আছে updated_atটাইমস্ট্যাম্প:

if created_at == updated_at
  # it's a newly created record
end

কোনও খারাপ ধারণা নয়, তবে মনে হচ্ছে এটি কিছু পরিস্থিতিতে পিছিয়ে যেতে পারে (বুলেট প্রুফের অগত্যা নয়)।
অ্যাশ ব্লু

যখন কোনও মাইগ্রেশন চালানো হয় তার উপর নির্ভর করে তৈরি_আট এবং আপডেট_এটি রেকর্ড বন্ধ হয়ে যেতে পারে। এছাড়াও আপনি সর্বদা কারও রেকর্ডটি সঠিকভাবে সংরক্ষণের পরে আপডেট করার সুযোগটি চালান যা সময়টিকে কেবল সিঙ্কের বাইরে রাখে। এটি কোনও খারাপ ধারণা নয়, কেবল মনে হচ্ছে আরও বুলেট প্রুফ বাস্তবায়ন যুক্ত করা যেতে পারে।
অ্যাশ ব্লু

প্রাথমিকভাবে রেকর্ডটি তৈরি হওয়ার পরে তারা সমান হতে পারে। কয়েক মাস ধরে কোনও রেকর্ড আপডেট না হলে এটি সবেমাত্র তৈরি হয়েছিল বলে মনে হচ্ছে ।
bschaeffer

4
@bschaeffer দুঃখিত, আমার প্রশ্ন ছিল "এটির জন্য সম্ভব created_atসমান updated_atএকটি ইন after_saveকোনো যখন এটি প্রথম তৈরি করা হয় ছাড়া অন্য সময়ে কলব্যাক?"
কল্লিন

4
@ কল্লিন: একটি রেকর্ড তৈরি করার সময়, created_atএবং updated_atএকটি after_saveকলব্যাকে সমান হবে । অন্যান্য সমস্ত পরিস্থিতিতে, after_saveকলব্যাকে তারা সমান হবে না ।
বিএসএফার

22

একটি after_createকলব্যাক রয়েছে যা কেবলমাত্র রেকর্ডটি যদি নতুন রেকর্ড হয় তবে এটি সংরক্ষণ করা হয়after_updateব্যবহারের জন্য একটি কলব্যাকও রয়েছে যদি এটি কোনও বিদ্যমান রেকর্ড যা পরিবর্তন ও সংরক্ষণ করা হয়েছিল। after_saveকলব্যাক, উভয় ক্ষেত্রেই বলা পর পারেন হয় after_createবা after_updateবলা হয়।

after_createকোনও নতুন রেকর্ড সংরক্ষণের পরে যদি আপনার কিছু হওয়ার দরকার হয় তবে ব্যবহার করুন ।

এখানে আরো তথ্য: http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html


4
আরে, উত্তরের জন্য ধন্যবাদ, এটি আমাকে অনেক সাহায্য করেছিল। চিয়ারস ম্যান, +10 :)
অ্যাডাম ম্যাকআর্থার

4
এটি আসলে সত্য হতে পারে না। আপনার সৃষ্টিতে যদি আপনার সহযোগীতা থাকে, তবে অ্যাসোসিয়েশনগুলি তৈরি হওয়ার আগে_ক্রেইটকে বলা হয়, সুতরাং যদি আপনাকে নিশ্চিত করা দরকার যে সমস্ত কিছু তৈরি হয়েছে, তবে আপনাকে পরে_সামার ব্যবহার করতে হবে
নীলস ক্রিশ্চিয়ান

18

যেহেতু বস্তুটি ইতিমধ্যে সংরক্ষণ করা হয়েছে, আপনার পূর্ববর্তী পরিবর্তনগুলি লক্ষ্য করা উচিত। আইডি শুধুমাত্র একটি তৈরির পরে পরিবর্তন করা উচিত।

# true if this is a new record
@object.previous_changes[:id].any?

উদাহরণস্বরূপ পরিবর্তনশীলও রয়েছে @new_record_before_save। আপনি নিম্নলিখিতটি ব্যবহার করে এটি অ্যাক্সেস করতে পারেন:

# true if this is a new record
@object.instance_variable_get(:@new_record_before_save)

উভয়ই বেশ কুৎসিত, তবে তারা আপনাকে জানাতে দেবে যে অবজেক্টটি নতুনভাবে তৈরি হয়েছে কিনা। আশা করি এইটি কাজ করবে!


আমি বর্তমানে after_saveরেল 4 ব্যবহার করে একটি কলব্যাকে বাইবগে আছি এবং এর মধ্যে দুটিও এই নতুন রেকর্ডটি সনাক্ত করতে কাজ করছে না।
এমসিবি

আমি বলতে চাই যে @object.previous_changes[:id].any?এটি বেশ সহজ এবং মার্জিত। রেকর্ডটি আপডেট হওয়ার পরে এটি আমার পক্ষে কাজ করে (আমি এটিকে কল করি না after_save)।
thekingoftruth

4
@object.id_previously_changed?কিছুটা কুরুচিপূর্ণ।
নোবল

after_save4 টি এমপিবি 4 রেলগুলিতে প্রবেশ করুন যা আপনি এর changes[:id]পরিবর্তে দেখতে চান previous_changes[:id]। এই Rails5.1 পরিবর্তিত হচ্ছে কিন্তু (ইন আলোচনা দেখুন github.com/rails/rails/pull/25337 )
gmcnaughton

4
previous_changes.key?(:id)আরও ভাল বোঝার জন্য।
সেবাস্তিয়ান পালমা


1

রেল 4 এর জন্য (4.2.11.1 এ চেক করা হয়েছে) এর ফলাফল changesএবং previous_changesপদ্ধতিগুলি হ'ল হ্যাশগুলি হ'ল {}অবজেক্ট তৈরির ভিতরে after_save। সুতরাং যেমন attribute_changed?পদ্ধতি id_changed?প্রত্যাশার মতো কাজ করবে না।

তবে আপনি এই জ্ঞানের সুবিধা নিতে পারেন এবং - কমপক্ষে 1 টি বৈশিষ্ট্য changesআপডেট হতে হবে তা জেনে - changesখালি কিনা তা পরীক্ষা করে দেখুন । একবার আপনি এটি খালি করার বিষয়ে নিশ্চিত হয়ে গেলে আপনাকে অবশ্যই অবজেক্ট তৈরির সময় থাকতে হবে:

after_save do
  if changes.empty?
    # code appropriate for object creation goes here ...
  end
end

0

আমি নির্দিষ্ট হতে চাই এমনকি আমি সচেতন যে :idস্বাভাবিকের মধ্যে পরিবর্তন হওয়া উচিত নয়, তবে

(byebug) id_change.first.nil?
true

খুব অদ্ভূত অপ্রত্যাশিত বাগটি সন্ধানের পরিবর্তে সুনির্দিষ্ট হওয়ার জন্য এটি সর্বদা সস্তা।

একইভাবে যদি আমি trueঅবিশ্বস্ত যুক্তি থেকে পতাকা প্রত্যাশা করি

def foo?(flag)
  flag == true
end

অদ্ভুত বাগগুলিতে না বসে এটি প্রচুর ঘন্টা সাশ্রয় করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.