@user = User.find(params[:id])
So I created a simple method, stuck it in application_controller.rb, and thinned out my controller a bit more.But then, once my apps got bigger and more complex, I found my application controller was getting chubby with record fetchers! So I started to look for a solution, and here is what I came up with. Create a single fetcher method and have it accept an argument to tell what model to refer to. This is how it looks at the moment:
def fetch_record(record)
begin
eval "@#{record} = #{record.capitalize}.find(params[:id])"
rescue NameError #raised when a non-existing model is called.
render file: 'public/500.html', status: 500
end
end
begin
eval "@#{record} = #{record.capitalize}.find(params[:id])"
rescue NameError #raised when a non-existing model is called.
render file: 'public/500.html', status: 500
end
end
The eval function is quite useful in this case, executing the string after it is evaluated.
A problem that arises is, how do you call a before_filter method with arguments?
Well, after digging around for a while, I found the solution is using a proc:
before_filter { |controller| controller.send(:fetch_record, "user") }
This will call that fetch_record method and send "user" as a parameter. However it will do so for every action, and that's not good.The method before_filter itself may also receive a hash of options such as :only and :except, to restrict which actions will execute the called method. But in this case, the hash must be passed a little differently - in parentheses, before the proc:
before_filter(only: [:show, :edit, :update, :destroy]) { |controller| controller.send(:fetch_record, "product") }
I'm quite happy with this improvement so far, but I would be glad to hear if there are better practices out there you guys have seen or came up with.
No comments:
Post a Comment