Problem writing to database using form_for

Hi,

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.

Thanks in advance.

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

end

then on an after save

session[:mysterous_object] = nil

Radhames Brito wrote:

save it in the session hash on validation

Hi,

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:
http://www.ruby-forum.com/topic/160769

If I have misunderstood you please let me know.

How about this ?

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.

Luke

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.

I really appreciate any help.

Perhaps you could post the pertinent code ? Do you have validation checks in the form (via javascript) or just the ones in model ?

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

Another approach might be to pass this value from the new action to the create action through the form using a hidden field.

Luke

Hi Luke,

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.

Thanks very much for your help.

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.

I think Jim is querying whether one can access the session variable
from within the model, and even if one can, whether one should.

Colin

I think Jim is querying whether one can access the session variable

from within the model, and even if one can, whether one should.

Oh i see, well i will test if is available in the model and if possible ill see if there a problem with it.