【问题标题】:How to make a model callback conditional based upon controller actions [:create, :update]?如何根据控制器操作 [:create, :update] 使模型回调有条件?
【发布时间】:2015-09-10 19:48:23
【问题描述】:

我想在 goal.rb

中做类似的事情
  before_save :set_tag_owner,:if => [:create, :update]

  def set_tag_owner
    # Set the owner of some tags based on the current tag_list
    set_owner_tag_list_on(self.user, :tags, self.tag_list)
    self.tag_list = nil
  end

我希望此方法在保存之前仅适用于 goals_controller 的创建和更新操作。

否则我会遇到标记问题,即当一个目标被标记为已完成时,该标记就会消失,因为set_tag_owner 将其标记设置为nil

  def mark_accomplished
    @goal.update(accomplished: true)
  end

  def create
    @goal = current_user.goals.build(goal_params)
    @goal.save
    respond_modal_with @goal, location: root_path, notice: 'Goal was successfully created! Go chase those dreams!'
  end

  def update
    @goal.update(goal_params)
    respond_modal_with @goal, location: root_path
  end

虽然self.tag_list = nil 我需要这条线,因为没有它,标签会被双重渲染

我还尝试通过before_action 回调在控制器内应用该目标模型逻辑,但即使我将self 更改为@goal,我也会收到undefined 错误。

【问题讨论】:

  • 为什么不在控制器的创建和更新方法中简单地调用 set_tag_owner 呢?
  • 如果您只想在创建或更新记录时执行set_tag_owner,不应该调用哪些操作?因为我不明白你为什么需要这个......
  • @MrYoshiji 不应该在mark_accomplished 上调用它。现在,如果用户单击触发mark_accomplished 的按钮,与该目标关联的标签就会消失。我对更新操作没有这个问题,因为当用户更新目标时,表单会重新填充标签。
  • 你可能想从源头上解决问题,而不是在它发生时试图避免它......但我可以理解,摆脱这个双重渲染问题并不容易。 ..我昨天看到了你的另一篇文章,找不到适合你的解决方案:/
  • 我试图做到这一点@bumpy。也许我做错了。你能告诉我那会是什么样子吗?例如,我将set_owner_tag_list_on(@goal.user, :tags, @goal.tag_list) @goal.tag_list = nil 放入创建中,我得到错误:undefined method 'set_owner_tag_list_on'

标签: ruby-on-rails ruby model-view-controller tags acts-as-taggable-on


【解决方案1】:

另一种方法是在模型中添加 attr_accessor 并使用它来停止 before_save

一个例子

class Goal < ActiveRecord::Base

  attr_accessor :dont_set_tag_owner

  before_save :set_tag_owner, :unless => dont_set_tag_owner

  def set_tag_owner
    # Set the owner of some tags based on the current tag_list
    set_owner_tag_list_on(self.user, :tags, self.tag_list)
    self.tag_list = nil
  end

end

然后,在控制器中

def mark_accomplished
  @goal.update(accomplished: true, :dont_set_tag_owner => true)
end

而且,只是给你一个更多的选择 - 根据你对 updated_at 的需求,你也可以这样做

def mark_accomplished
  @goal.update_column(accomplished: true)
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多