Rails:仅为CRUD操作运行回调?

时间:2014-01-26 03:00:28

标签: ruby-on-rails ruby activerecord

我在Rails 3.这是我的一个方法的代码,该方法创建Update记录以响应在名为Candidate的模型上更改的某些属性:

before_save :check_changed, on: [:update]
def check_changed
  tracked_attributes = ["period_contributions", "total_contributions",
                        "period_expenditures", "total_expenditures",
                        "debts_and_loans", "cash_on_hand",
                        "major_endorsements",
                        "rating_afl_cio",
                        "rating_cal_tax",
                        "rating_cc",
                        "rating_eqca",
                        "rating_lcv",
                        "rating_now"]
  changes.each do |key, value|
    if tracked_attributes.include?(key)
      Update.create(:candidate_id => self.id, :attribute_name => key, 
    :new_value => value[1], :old_value => value[0])
    end
  end
end

问题是我正在运行一些rake任务来对数据进行批量更新,这最终会无意中触发此回调。我只想在管理工具(即CRUD界面)中更新候选人时运行它。有关最佳方法的建议吗?

1 个答案:

答案 0 :(得分:1)

我只会在需要发生的事情时使用回调,无论来源如何。神奇地跳过或包含它们通常会导致痛苦。

我的建议是在模型上创建一个不同的方法来执行检查并将其用于crud操作。

class Candidate
  #...

  def check_changed_and_update(attributes)
    check_changed
    update(attributes)
  end

  private

  def check_changed
    tracked_attributes = ["period_contributions", "total_contributions",
                          "period_expenditures", "total_expenditures",
                          "debts_and_loans", "cash_on_hand",
                          "major_endorsements",
                          "rating_afl_cio",
                          "rating_cal_tax",
                          "rating_cc",
                          "rating_eqca",
                          "rating_lcv",
                          "rating_now"]
    changes.each do |key, value|
      if tracked_attributes.include?(key)
        Update.create(:candidate_id => self.id, :attribute_name => key,
                      :new_value => value[1], :old_value => value[0])
      end
    end
  end
end

然后在候选人的控制器中将update更改为check_changed_and_update

class CanidateController < ApplicationController
  def update
    #...
    respond_to do |format|
      if @candidate.check_changed_and_update(canidate_params)
        format.html { redirect_to @candidate, notice: 'Candidate was successfully updated.' }
      else
        format.html { render action: 'edit' }
      end
    end
  end

这有一个额外的好处,可以明白在调用更新时会发生什么。

现在,您可以在rake任务中使用正常的活动记录api。