Forum: Ruby on Rails Cannot set date value

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
171ea139761951336b844e708d1547ab?d=identicon&s=25 James Byrne (byrnejb)
on 2009-03-23 22:31
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?
81b61875e41eaa58887543635d556fca?d=identicon&s=25 Frederick Cheung (Guest)
on 2009-03-23 23:12
(Received via mailing list)
On Mar 23, 9:31 pm, James Byrne <rails-mailing-l...@andreas-s.net>
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
171ea139761951336b844e708d1547ab?d=identicon&s=25 James Byrne (byrnejb)
on 2009-03-24 14:45
Frederick Cheung 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.
81b61875e41eaa58887543635d556fca?d=identicon&s=25 Frederick Cheung (Guest)
on 2009-03-24 15:42
(Received via mailing list)
On Mar 24, 1:45 pm, James Byrne <rails-mailing-l...@andreas-s.net>
wrote:
> Rails date chooser, which I am not using.
ah, you should have said :-)

>  @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
171ea139761951336b844e708d1547ab?d=identicon&s=25 James Byrne (byrnejb)
on 2009-03-24 16:06
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?
171ea139761951336b844e708d1547ab?d=identicon&s=25 James Byrne (byrnejb)
on 2009-03-24 16:31
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.
171ea139761951336b844e708d1547ab?d=identicon&s=25 James Byrne (byrnejb)
on 2009-03-24 16:33
James Byrne wrote:

> I suppose that I should use method_missing instead.

Or instead, has-attribute?
81b61875e41eaa58887543635d556fca?d=identicon&s=25 Frederick Cheung (Guest)
on 2009-03-24 22:39
(Received via mailing list)
On 24 Mar 2009, at 15:33, James Byrne wrote:

>
> James Byrne 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
171ea139761951336b844e708d1547ab?d=identicon&s=25 James Byrne (byrnejb)
on 2009-03-25 21:33
Frederick Cheung 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.
This topic is locked and can not be replied to.