What is the best practices place to manipulate form data before saving in Rails 3?
From the pointview of rails best practices, what is the best place to manipulate form data before saving?
For instace, on a contact form, I want to make sure that all data is saved in capitalized form ( don't you hate when PEOPLE SHOUT AT YOU in their "please contact me" form submission? :-) )
- is it better to do manipulation in controller? I could either do it in create, or move it into some sort of private method , that will capitalize all string attributes of the object before saving / updating?
Or
- is it better do in the model before_save? It makes sense to me that it should be done in the model since I probably want that to be the same for all records, no matter whether I manipulate on them in a rake task or through the web interface.
Bonus:
Also where would I place it if I want that that on ALL my models, with the ability to override default on a case by case basis? Application controller? There might be some special cases where you want to save value without capitalizing - i.e. brand name products that don't capitalize (i.e. utorrent) or a last name that should have multiple caps in the name 开发者_如何学编程(i.e. Irish & Scottish names like McDonald)
Thank you!
the easiest place to put this is in your model. I would suggest using either before_save or even before_validation if you feel that fits better. Something like this would do the trick:
before_save :upcase_content
def upcase_content
self.content = self.content.upcase
end
Additionally if you wanted to allow for exceptions of a case by case basis you could add an attr_accessor to your model.
class MyModel < ActiveRecord::Base
attr_accessor :dont_upcase
before_save :upcase_content, :unless => :dont_upcase
...
end
then when you create a model set the accessor to true
@model = Model.new(:brand_name => utorrent)
@model.dont_upcase = true
@model.save!
The best place to put this is in your model, that way you have a fat model and a skinny controller, which is a "good thing".
If you want to have this be available for all of your models my suggestion is to use a module which contains your shared functionality and then include that in all the models you want to have the default behavior.
Ok based on the suggestions from other replies I came up with this solution:
lib/clean_strings.rb
module ActiveRecord
class Base
attr_accessor :dont_capitlize, :dont_strip
before_save :_capitalize_strings, :unless => :dont_capitlize
before_save :_strip_whitespaces, :unless => :dont_strip
def _capitalize_strings
self.attributes.each_pair do |key, value|
self[key] = value.capitalize if value.respond_to?('capitalize')
end
end
def _strip_whitespaces
self.attributes.each_pair do |key, value|
self[key] = value.strip if value.respond_to?('strip')
end
end
end
end
in environment.rb addded
require "clean_strings"
Now whenever I do
@a.dont_capitalize = true
@a.save!
it cleans it before saving according to my rules ( it will strip whitespace, but not capitalize it ). Obviously it needs more fine tuning, but i think it's a good way to define format rules for commonplace things. This way I don't need to sanitize every and each form input for things like extra whitespaces, or people who don't know where the CAPS LOCK is !!!
Thank you all for your input ( all upvoted).
精彩评论