【问题标题】:Using Rails model to update to change one boolean value based on another使用 Rails 模型更新以根据另一个布尔值更改一个布尔值
【发布时间】:2013-09-21 19:03:32
【问题描述】:

我正在尝试制作一个宠物轨道应用程序。我的宠物模型包含两个布尔值,饥饿和 feed_me。现在,可以在视图中设置饥饿和 feed_me,但我正在尝试设置模型,以便如果 feed_me 为真,饥饿将自动更改为假。然而,无论我做什么,feed_me 都不会重置饥饿。这就是我现在模型中的内容:

    attr_accessor :feed_me
    before_save :feed


     def feed
       @feed_me = Creature.find(params[:feed_me])
       @hungry=Creature.find(params[:hungry])
       if @feed_me==true
         @hungry=false
       end 
    end

我是 Rails 新手,但我的理解是模型应该可以访问 params 哈希,所以我很困惑为什么我不能使用它来重置值。

【问题讨论】:

  • 您需要 :feed_me 栏吗?你可以通过一个 :hungry 布尔列来简化你的 Creature 模型。例如,如果 :feed_me 是在一个生物 :hungry 5 小时后才发生的事情,那么你可以即时计算而不是存储在数据库中。
  • 你知道,我不认为我真的需要它——我想让用户能够在宠物饿的时候喂它,让它不饿。这是我应该用辅助函数做的吗?
  • 您甚至可以只拥有一个last_fed_at 列(日期时间)。这样你就可以有一个@creature.hungry? 方法,它是这样实现的:last_fed_at > 5.hours.ago(只有在 5 小时内没有被喂食的生物才会饿)。那么你可以有一些逻辑:如果@creature.hungry?然后显示 FEED ME 按钮。并且 FEED ME 按钮只调用 @creature.feed 方法,该方法执行 @creature.update_column(:last_fed_at, Time.now)。现在@creature.hungry?是错误的,因为它的 last_fed_at 已更新到现在。这有意义吗?
  • 这真是个好主意 - 我可以把它放在视图中吗?
  • 在视图中,您可以输入if @creature.hungry? then display <FEED BUTTON> 将指向CreaturesController#feed 操作。 feed 操作可以有代码if @c = current_user.creatures.find(params[:id]) && @c.feed then redirect_to(@c, notice: "Creature was fed!")。显然,我在此评论中没有太多空间,但我希望你能明白。

标签: ruby-on-rails ruby ruby-on-rails-3


【解决方案1】:

您使用模型回调走在正确的轨道上,但是模型无法访问 param 哈希 - 它可供控制器使用。

模型已经知道它自己的属性的值,所以你不需要从参数中获取它们。我想象的控制器正在更新feed_me

此外,假设 feed_me 由数据库列支持,您不需要将其声明为 attr_accessor

您可以将before_save 更改为:

def feed
  if self.feed_me
    self.hungry = false
  end
end

在您的控制器中,我想您会执行以下操作:

def update
  pet = Pet.find(params[:id])
  pet.feed_me = params[:feed_me]

  if pet.save
    redirect_to pet_path(pet)
  else
    flash[:notice] = 'Error saving pet'
    render :edit
  end
end

【讨论】:

  • 这是控制器现在的样子:def update creature = Creature.find(params[:id]) creature.feed_me = params[:feed_me] creature.hungry = params[:hungry] respond_to do |format| if @creature.update(creature_params) format.html { redirect_to @creature, notice: 'Creature was successfully updated. #{params[:feed]}' } format.json { head :no_content } else format.html { render action: 'edit' } format.json { render json: @creature.errors, status: :unprocessable_entity } end end end
  • 我还按照您的建议更新了模型 - 我对现在实际调用提要的时间感到困惑。我会从控制器中做到这一点吗?
  • 如果你的模型中现在有一个'before_save :feed',正如 Michael 建议的那样,它会在保存模型的过程中被调用 - 当你调用 @creature.update 时最初在你的控制器中触发。
  • 奇怪的是它没有更新,当我尝试检查它时,我得到了奇怪的东西。当我尝试创造 [:name].inspect 时,我得到了这个名字。当我尝试 bio[:feed_me].inspect 时,我得到 nil,但是当我尝试 params.inspect 时,我得到这个哈希:``` {"utf8"=>"✓", "_method"=>"patch" , "authenticity_token"=>"kqboasdfasdfasdf=", "creature"=>{"name"=>"Bob", "hungry"=>"1", "feed_me"=>"1", "mood"=>" lazy"}, "commit"=>"更新 Creature", "action"=>"update", "controller"=>"creatures", "id"=>"1"}```
  • 看起来您应该使用params[:creature][:hungry]params[:creature][:feed_me](与生物模型相关的所有参数都将保存在params 哈希的:creature 键中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-06
  • 1970-01-01
  • 2022-07-11
  • 2018-03-05
相关资源
最近更新 更多