如何在控制器操作

时间:2016-11-15 22:11:07

标签: ruby-on-rails ruby

我有一个操作只是将#active属性切换到相反的布尔状态:

  • 如果@blog.active == true然后update将其设为无效
  • 如果@blog.active == false然后update将其激活

我在控制器中得到了以下自定义操作,但是必须有一些Rails方法才能更优雅地执行此操作:

class BlogsController < ApplicationController

  ...    

  def toggle_active
    if @blog.active?
      @blog.update(active: false)
    else
      @blog.update(active: true)
    end
  end

end

是否有一种Rails方式将布尔属性更新为相反的布尔状态?

5 个答案:

答案 0 :(得分:15)

Active Record的toggletoggle!方法处理切换布尔属性:

def toggle_active
  @blog.toggle(:active).save
end
def toggle_active
  @blog.toggle!(:active)
end

toggle更改了该属性,但未将更改保存到数据库(因此需要单独调用savesave!。)

toggle!更改属性并保存记录,但绕过模型的验证。

答案 1 :(得分:7)

Rails为此提供toggle,但它不是原子,您仍然需要调用save并考虑验证。 bang-method替代方案将为您处理持久性,但会跳过验证。

最好明确一下你想要做什么。如果此操作是表单POST或XHR请求的结果,则接受您要设置的实际值(RESTful),而不是期望客户端知道数据库的当前状态。

所以虽然这有效:

@blog.toggle(:active)

......这是非确定性的,可能导致与所需行动相反。我建议改为:

class BlogStatusController < ApplicationController 
  # ... boilerplate to load @blog
  def update
    @blog.update(status_params)
  end

protected

  def status_params
    params.require(:blog).permit(status: [:active])
  end
end

如果您需要原子切换,您可以使用方便的方法名称包装的SQL语句轻松实现它:https://stackoverflow.com/a/24218418/203130

答案 2 :(得分:5)

这应该有效:

@blog.update(active: !@blog.active?)

!是你的朋友:

!false # => true
!true # => false

答案 3 :(得分:5)

ActiveRecord具有执行此操作的toggletoggle!方法。请记住,toggle!方法会跳过验证检查。

class BlogsController < ApplicationController

  ...    

  def toggle_active
    @blog.toggle!(:active)
  end

end

如果您想运行验证,可以

@blog.toggle(:active).save

您可以阅读方法here

的源代码

答案 4 :(得分:2)

你可以试试这个:

@blog.update(active: !@blog.active?)

那非常紧凑。