我有一个使用 rails 生成的脚手架的条目的表输出:CRUD ops。
如果我想在桌子上做另一个动作,比如默认的“显示、编辑、销毁”,比如图书馆的书“签到”,那会将状态更新为“签到”......
使用模型和控制器进行更新的正确方法是什么?(使用 mongodb)
更好地说明:拥有许多自定义操作的最佳方式是什么?把它想象成许多多用途的“Facebook Likes”。
在桌子上,动作列表“打这个”,“看看这个”......
我有一个使用 rails 生成的脚手架的条目的表输出:CRUD ops。
如果我想在桌子上做另一个动作,比如默认的“显示、编辑、销毁”,比如图书馆的书“签到”,那会将状态更新为“签到”......
使用模型和控制器进行更新的正确方法是什么?(使用 mongodb)
更好地说明:拥有许多自定义操作的最佳方式是什么?把它想象成许多多用途的“Facebook Likes”。
在桌子上,动作列表“打这个”,“看看这个”......
有很多方法可以处理这个问题,但我通常喜欢在他们自己的控制器操作中用它自己的路由隔离这样的操作。
为了保持整洁,我建议在模型中添加一个方法来更新您关注的属性。如果您不关心验证,您可以使用update_attribute
. 此方法跳过验证并保存到数据库
class LibraryBook < ActiveRecord::Base
def check_in!
self.update_attribute(:checked_in, true)
end
end
您需要更新index.html.erb
视图以添加更新单个记录的链接。这也需要添加一条路线。由于您正在更新记录,因此您需要使用 PUT HTTP 动词。
resources :library_books do
match :check_in, on: :member, via: :put # creates a route called check_in_library_book
end
添加链接
link_to check_in_library_book_path(library_book), method: :put
现在您需要在调用该#check_in!
方法的控制器中添加操作。
class LibraryBooksController < ApplicationController
def check_in
@library_book = LibraryBook.find(params[:id])
if @library_book.check_in!
# Handle the success
else
# Handle the Failure
end
end
end
在我看来,处理这种状态工作流的最佳方法是从事件的角度来考虑它,然后将状态视为最近的事件。我通常创建一个event_type
带有name
and的表code
(例如Check In
,CHECK_IN
分别用于名称和代码),然后创建一个event
带有event_type_id
, 时间戳的表,通常是某种用户 ID 或 IP 地址,或两者兼而有之。
然后你可以这样说:
class Thing < ActiveRecord::Base
has_many :events
def status
events.order("created_at DESC").first.event_type.name
end
end
那里也有“审计线索”宝石,但在我(有限的)经验中,它们并不是很好。
这与 MongoDB 无关,实际上可能与 Mongo 不兼容,但希望它至少为您指明正确的方向或给您一些想法。