Cannot set date value


#1

I have this controller code:

field_array.each do |f|
f = f.to_sym
model.send("#{f}=", “#{parm_hash[f]}”) if
model.attribute_present?(f)
end
return model

field_array is an array of attribute names as strings.
parm_hash is the params hash returned from the view associated with
model.

If the value associated with an attribute_key is anything but a date
then this works and the value is set. If the value is a date then it
sets nil instead.

Can anyone see what I am doing wrong?


#2

On Mar 23, 9:31 pm, James B. removed_email_address@domain.invalid
wrote:

field_array is an array of attribute names as strings.
parm_hash is the params hash returned from the view associated with
model.

If the value associated with an attribute_key is anything but a date
then this works and the value is set. If the value is a date then it
sets nil instead.

because with a date you can’t pull the value from the params hash in
one go like that - there is one value in the hash for each component
(day, month, year). There’s more about this at
http://www.spacevatican.org/2008/12/3/dates-params-and-you

Fred


#3

Frederick C. wrote:

because with a date you can’t pull the value from the params hash in
one go like that - there is one value in the hash for each component
(day, month, year). There’s more about this at
http://www.spacevatican.org/2008/12/3/dates-params-and-you

Fred

I looked at this reference, but it seems to relate specifically to the
Rails date chooser, which I am not using. I dumped the hash contents
passed to the code thus:

  print parm_hash.to_yaml
  field_array.each do |f|
    f = f.to_sym
    model.send("#{f}=", "#{parm_hash[f]}") if 

model.attribute_present?(f)
end
return model

This is what I get:

— !map:HashWithIndifferentAccess
client_credit_limit: “250”
superseded_after__dteblk: “”
effective_from__dteblk: 2009-03-24 09:31:16 -0400
client_credit_status: INAC
client_credit_policy: OPEN
effective_from: 2009-03-24 09:31:16 -0400
superseded_after: “”
client_credit_terms: “15”

As far as I can tell from this there are no nested hashes of any type
and the value for 'effective_from is a datetime value.

This code should resolve to:
@client.send(“effective_from=”,2009-03-24 09:31:16 -0400)

And should be equivalent to:
@client.effective_from=params[:client][:effective_from]

Which works without error.


#4

On Mar 24, 1:45 pm, James B. removed_email_address@domain.invalid
wrote:

Rails date chooser, which I am not using.
ah, you should have said :slight_smile:

@client.send(“effective_from=”,2009-03-24 09:31:16 -0400)

Are you sure this is getting called ? perhaps attribute_present? is
returning false (if the previous value of the attribute was nil)

Fred


#5

Well, I discovered the proximate cause why effective_date is not set,
but I do not know why this is happening.

  field_array.each do |f|
    #puts parm_hash[f].class
    f = f.to_sym
    puts "have #{f}"    if model.attribute_present?(f)
    puts "missing #{f}" unless model.attribute_present?(f)
    model.send("#{f}=", "#{parm_hash[f]}") if 

model.attribute_present?(f)
end

gives:

missing effective_from
have client_credit_limit
have client_credit_policy
have client_credit_status
have client_credit_terms
missing superseded_after

So, why would the model report the attribute as missing? The view for
this looks like this:

  <%= f.text_field  :effective_from,
                    :size => 12,
                    :class => 'datebalks'
  -%>

  <%= f.text_field  :superseded_after,
                    :size => 12,
                    :class => 'datebalks'
  -%>

annotate gives this:

== Schema Information

Schema version: 20090312200034

Table name: clients

id :integer not null, primary key

entity_id :integer not null

client_credit_limit :integer default(0), not null

client_credit_policy :string(4) default(“CASH”), not null

client_credit_status :string(4) default(“HOLD”), not null

client_credit_terms :integer default(0), not null

effective_from :datetime

superseded_after :datetime

changed_at :datetime

changed_by :string(255)

created_at :datetime not null

created_by :string(255)

lock_version :integer default(0), not null

and the attribute is self-evidently present because this code:

  field_array.each do |f|
    #puts parm_hash[f].class
    f = f.to_sym
    puts "have #{f}"    if model.attribute_present?(f)
    puts "missing #{f}" unless model.attribute_present?(f)
    model.send("#{f}=", "#{parm_hash[f]}") if 

model.attribute_present?(f)
end
puts model.id
puts model.effective_from
puts model.does_not_exist
return model

Fails here:
undefined method `does_not_exist’ for #Client:0x2b917dbb34a8

and not on:
puts model.effective_from

Any ides as to what is going on?


#6

Ahh. As you point out, attribute_present? does not refer to the
attribute itself, but to its current value. I should think that given
the PoLS this method would be better called attribute_set? but no
matter.

I suppose that I should use method_missing instead.


#7

James B. wrote:

I suppose that I should use method_missing instead.

Or instead, has-attribute?


#8

On 24 Mar 2009, at 15:33, James B. wrote:

James B. wrote:

I suppose that I should use method_missing instead.

Or instead, has-attribute?
You could use ModelClass.column_names / ModelClass.columns_hash to see
if an appropriately named column exists.

Fred


#9

Frederick C. wrote:

You could use ModelClass.column_names / ModelClass.columns_hash to see
if an appropriately named column exists.

As far as I can tell from the code, that is pretty much what
has_attribute? does. However, upon reflection I realized that my
approach did not accommodate virtual attributes. So, I ended up with
this:

def attr_set_by_names(attr_names=[],param_hash={})
an = attr_names.to_ary
return self unless param_hash.kind_of?(Hash) && an.length > 0
an.each do |f|
self.send("#{f}=", “#{param_hash[f]}”) if
self.method_exists?("#{f}=")
end
return self
end

Which handles every setter method available to the class.

You assistance, as always, is greatly valued.