I have a web-based form for applicants to enter their details, created
using form_for :applicant
There is one field in the corresponding applicants table of my database
which is not represented in the form.
I want to set the value of this field in the model (it should be an
unique hash).
What is the best way to do this?
Currently I am doing:
validate do |applicant|
applicant.check_things
applicant.non_represented_field = 123456789
end
This works, but the value assigned to the 'non-represented' field is
only available after the applicants details have been successfully
saved.
If validation fails (i.e. if an obligatory field was omitted), this
value is showing up in the hash of values that is posted to the
controller as nil (which is bad as I always want it to be set).
I would be grateful if anyone could give me an idea how to solve this.
The only other thing I could think of was setting it with some kind of
call back, but I couldn't get that to work.
save it in the session hash on validation and delete it from the session hash after the save.
if validations fails, try to find the value on the session and putting it in the controller. Since validation will trigger again
in a second submit, also look for the value in the session hash before setting a new one.
validate do |applicant|
applicant.check_things
if
session[:mysterous_object].nil?
applicant.non_represented_field = session[:mysterous_object] = 123456789
else
applicant.non_represented_field = session[:mysterous_object]
end
Thanks for the reply.
Did I understand you correctly, that you are suggesting setting a
session variable in the model (where my validation is taking place)
which I can then pass to the controller?
I didn't know that that was possible.
Any hacks around this seem to be regarded as bad practice:
validate do |applicant|
errors.add_to_base("Things must check out!") unless
applicant.check_things
end
def before_save
applicant.non_represented_field = 123456789
end
before_save will only be called if your validations pass, so
non_represented_field will only be assigned to valid records.
Hi,
Thanks for the reply.
Sorry, I don't think I expressed myself very well.
When I submit the form, every value the applicant has entered is
validated and passed to the controller. That means that if they enter a
value in the email field (for example) I can access this value in the
controller in the params hash, regardless of whether validation failed
or passed.
As this 'non-represented' field is only getting set after a successful
validation, it is not available in the params hash until everything has
been filled out correctly. Before that it always shows as nil.
I would like to set this value in my model with every form submission
(it is a hash which is always a different value per submission) so that
it is always available in the params has in the controller.
Thanks very much for the reply.
You pointed me in exactly the right direction to solve my problem!!
Another approach might be to pass this value from the new action to the
create action through the form using a hidden field.
I tried this already. This had the disadvantage that the hidden field
was never up-to-date as it was set during validation and thus always
contained the value of the previous submission.
blah = Blah.new(params[:blah])
#now you have a instance of Blah.
if blah.save
#now you have access to the non represented field
blah.non_represented_field
end
This on the other hand, sorted me right out.
I changed it slightly to:
applicant = Applicant.new(params[:applicant])
if applicant.valid?
#now I have access to the field I need
do_stuff_with_non_represented_field
applicant.save
end
What I was actually using this field for was to create a hash of all
submitted values, compare it to the hash of the previous record and thus
prevent double data submission. And it works wonderfully.
are you use to using the flash? like flash[:notice]? well the session[:] object is just like it, it exits across request and it exist in the context of th user, that is, each user has its on session object. The difference is that what you store in the flash is deleted after one request but what you store in session is there untill the session is reset or you delete the object. Is often used in ecomerce app to store the cart like this session[:cart], and you can store anything in it. In fact storing options can be set to make it store in the DB.