মডেল থেকে বৈশিষ্ট্য পরিবর্তনগুলি কীভাবে সনাক্ত করবেন?


86

আমি রেলগুলিতে কলব্যাক ফাংশন তৈরি করতে চাই যা কোনও মডেল সংরক্ষণের পরে কার্যকর হয়।

আমার কাছে এই মডেল, দাবিটির একটি বিশিষ্ট 'স্ট্যাটাস' রয়েছে যা দাবির রাষ্ট্রের উপর নির্ভর করে পরিবর্তিত হয়, সম্ভাব্য মানগুলি মুলতুবি রয়েছে, অনুমোদিত, অনুমোদিত, প্রত্যাখ্যাত

ডেটাবেসটির 'স্থিতাবস্থা' এর ডিফল্ট মান সহ 'রাষ্ট্র' রয়েছে।

মডেলটি প্রথমবার তৈরি হওয়ার পরে বা একটি রাজ্য থেকে অন্য রাজ্যে আপডেট হওয়ার পরে কিছু কাজ সম্পাদন করতে চাই, তার উপর নির্ভর করে এটি কোন রাজ্য থেকে পরিবর্তিত হবে।

আমার ধারণাটি মডেলটিতে একটি ফাংশন রাখার জন্য:

    after_save :check_state

    def check_state
      # if status changed from nil to pending (created)
      do this

      # if status changed from pending to approved
      performthistask
     end

আমার প্রশ্ন হল আমি মডেলের মধ্যে পরিবর্তনের আগে কীভাবে পূর্বের মানটি পরীক্ষা করব?

উত্তর:


173

আপনার অ্যাক্টিভমডেল :: ডার্টি মডিউলটি দেখতে হবে: আপনার দাবি মডেলটিতে আপনার নিম্নলিখিত ক্রিয়া সম্পাদন করতে সক্ষম হওয়া উচিত:

claim.status_changed?  # returns true if 'status' attribute has changed
claim.status_was       # returns the previous value of 'status' attribute
claim.status_change    # => ['old value', 'new value'] returns the old and 
                       # new value for 'status' attribute

claim.name = 'Bob'
claim.changed # => ["name"]
claim.changes # => {"name" => ["Bill", "Bob"]}

উহু! রেলের আনন্দ!


6
মডেলটি সংরক্ষণ করার পরে এটি কাজ করবে না যা তিনি চেয়েছিলেন।
টম রসি

4
টমরোসি, dirtyকলগুলি কাজ করে after_save(উভয় প্রান্তে ২.৩ এবং ৩.x)। আমি এটি বেশ কয়েকবার ব্যবহার করেছি।
হরিশ শেঠি

11
@ টমরোসি, নোংরা পতাকাগুলি প্রতিশ্রুতিবদ্ধতার পরে পুনরায় সেট করা হয়েছে, সুতরাং সেগুলি after_commitরেল ৩.x এ প্রবর্তিত কলব্যাকগুলিতে উপলব্ধ হবে না। তারা অবশ্যই কাজ করবে after_save
হরিশ শেঠি

আমার কোন ধারণা ছিল না! আমি ভেবেছিলাম সেগুলি একবারে সংরক্ষণ হয়ে গেছে!
টম রসি

4
@ টমরোসি আমি কয়েক বছর আগে একই ধারণা নিয়ে শুরু করেছি। যখন আমি নোংরা পতাকাগুলি পরে_ সেভ করার সময় এটি পরীক্ষা করার চেষ্টা করলাম। সংক্ষেপে, এবং এর after_saveমধ্যে একটি রাষ্ট্রের জন্য কলব্যাক । ব্যতিক্রম ছুঁড়ে দিয়ে আপনি পুরো লেনদেনটি শেষ করতে পারেন । আপনি যদি বর্তমান অপারেশনটিকে প্রভাবিত করে সংরক্ষণের পরে কিছু করতে চান তবে :-) ব্যবহার করুনafter DMLbefore_commitafter_saveafter_commit
হরিশ শেঠি

38

আপনি এটি ব্যবহার করতে পারেন

self.changed

এটি সমস্ত কলামের একটি অ্যারে প্রদান করে যা এই রেকর্ডটিতে পরিবর্তিত হয়েছিল

আপনি ব্যবহার করতে পারেন

self.changes

যা অ্যারের হিসাবে ফলাফলগুলির আগে এবং পরে পরিবর্তিত কলামগুলির একটি হ্যাশ ফেরত দেয় as


7
কেবলমাত্র একটি ছোট্ট নোট যা এগুলিতে ব্যবহার self.করা অপ্রয়োজনীয় - আপনি কেবল বলতে পারেন changedএবং changes
ব্যবহারকারী 664833

@ user664833 আরও সুনির্দিষ্টভাবে বলা যায়, আপনি selfনিজেই মডেলটি এলে বাদ দিতে পারেন তবে আপনি যে কোনও বস্তুতে object.changedএবং এর সাথে এই কল করতে পারেন object.changes। :)
জোশুয়া পিন্টার

4

আমি আপনাকে প্রস্তাবিত স্টেট মেশিন প্লাগইনগুলির মধ্যে একবার দেখে নিন:

উভয়ই আপনাকে রাজ্যগুলির মধ্যে স্থিতিস্থাপকতা এবং ট্রানজিশন সেটআপ করতে দেয়। আপনার প্রয়োজনীয়তা পরিচালনা করার জন্য খুব দরকারী এবং সহজ উপায়।


আমি রুবিবাদী-আসামকে একবার চেষ্টা করছি। বলুন আমি ক্লাস দাবি করেছি <অ্যাক্টিভেকর্ড :: বেস এএএসএম আসাম_ক্লোনম অন্তর্ভুক্ত: স্থিতি: এসএম_ইনিটাল_স্টেট: মুলতুবি আছম_স্টেট: মুলতুবি,: enter =>: enter_pend Def enter_pend notifier.deliver_pend_notifications শেষ (স্ব) শেষ এবং আমার ডাটাবেসে আমার স্থিতির ক্ষেত্রে ডিফল্ট মান রয়েছে "বিচারাধীন" এর যদি আমি স্থিতি ক্ষেত্রটি পূরণ না করেই একটি দাবি করি re
ডেভিড সি

2

5.3+ রেলগুলির জন্য আপনার সক্রিয় রেকর্ড বৈশিষ্ট্য পদ্ধতিটি ব্যবহার করা উচিত: সেভড_চেঞ্জ_স_ট্রিবিউট?

সংরক্ষিত_পরিবর্তন_পরিবর্তন? (attr_name, ** বিকল্প) `

আমরা শেষ বার সংরক্ষণ করার পরে এই বৈশিষ্ট্যটি কি পরিবর্তন হয়েছিল? এই পদ্ধতিটির saved_change_to_name?পরিবর্তে প্রার্থনা করা যেতে পারে saved_change_to_attribute?("name")। অনুরূপ আচরণ attribute_changed?। এই পদ্ধতিটি কলব্যাকের পরে কার্যকরভাবে কলটি নির্দিষ্ট করার জন্য সেভ করার কলটি কার্যকর হয়েছে।

বিকল্পগুলি

from পাস হয়ে গেলে মূল পদ্ধতি প্রদত্ত বিকল্পের সমান না হলে এই পদ্ধতিটি মিথ্যা ফিরে আসবে

to পাস হয়ে গেলে, মানটি প্রদত্ত মানটিতে পরিবর্তন না করা পর্যন্ত এই পদ্ধতিটি মিথ্যা প্রত্যাবর্তন করবে

সুতরাং আপনার মডেলটি দেখতে এমন হবে, যদি আপনি বৈশিষ্ট্যের মান পরিবর্তনের ভিত্তিতে কোনও পদ্ধতি কল করতে চান:

class Claim < ApplicationRecord
  
  after_save :do_this, if: Proc.new { saved_change_to_status?(from: nil, to: 'pending') }

  after_save :do_that, if: Proc.new { saved_change_to_status?(from: 'pending', to: 'approved') }

  
  def do_this
    ..
    ..
  end

  def do_that
    ..
    ..
  end

end

এবং যদি আপনি কলব্যাকের মান পরিবর্তনের জন্য পরীক্ষা করতে না চান, আপনি নিম্নলিখিতটি করতে পারেন:

class Claim < ApplicationRecord

  after_save: :do_this, if: saved_change_to_status?


  def do_this
    ..
    ..
  end

end

0

আমি অনেক জায়গায় প্রশ্ন উত্থাপিত দেখেছি, তাই কোডটি আরও সুন্দর করার জন্য আমি এর জন্য একটি ক্ষুদ্র রুবিজেম লিখেছি (এবং সর্বত্র / যদি অন্যথায় বিবৃতি দেয় তবে মিলিয়ন এড়ানো): https://github.com/ronna-s / অন_চেঞ্জ । আমি আশা করি এটি সাহায্য করবে.


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