我有一个操作只是将#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方式将布尔属性更新为相反的布尔状态?
答案 0 :(得分:15)
Active Record的toggle
和toggle!
方法处理切换布尔属性:
def toggle_active
@blog.toggle(:active).save
end
def toggle_active
@blog.toggle!(:active)
end
toggle
更改了该属性,但未将更改保存到数据库(因此需要单独调用save
或save!
。)
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具有执行此操作的toggle
和toggle!
方法。请记住,toggle!
方法会跳过验证检查。
class BlogsController < ApplicationController
...
def toggle_active
@blog.toggle!(:active)
end
end
如果您想运行验证,可以
@blog.toggle(:active).save
您可以阅读方法here
的源代码答案 4 :(得分:2)
你可以试试这个:
@blog.update(active: !@blog.active?)
那非常紧凑。