[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
Re: [PhillyOnRails] ActiveRecord::new() and default table values
|
So in Chris' approach, I could do:
[code]
@product=products[0].clone
@product.id=products[0].id
@product.save!
[/code]
And this would work except that I have 'before_create' filters on
Product, and for some reason clone() loses all of the methods that
should be there. For example, self.kind='something' doesn't work in a
filter for @product as generated above. I can't rewrite all of the
before filters to muck around in the @attributes variable, because there
are just too many models to rewrite for this exception.
So, I'm settling for Evan's approach, using the "write_attribute"
function (which I see is also mentioned in the comments of
"active_record/base.rb") and removing the default value in the table
definition. It's not what I would like to do, but it is a step forward.
Thanks for your help; I hope this helps others on the list as well. If
anyone knows of a cleaner approach . . .
Thanks!
-Cassius
Evan wrote:
You can force a specific primary key by adding an id writer method to
your model:
def id= n; write_attribute :id, n; end
Then after instantiating the object with .new(hash), you can assign
.id= the new id. Then you can save the record and it will go in with
the id you want. (At least, that's how I worked around the problem in
my own code).
I don't know why your "kind" attribute isn't getting saved properly,
though.
Evan
On 10/18/06, Cassius Rosenthal <cassius@xmodulation.com> wrote:
Interesting approach. This breaks filters because the YAML object uses
strings instead of symbols to hash the attributes. Substituting strings
into filter functions [is ugly but] does solve the problem of :kind in
the example below overriding the table default; however, the id for the
object still is not preserved. In this case, it defaults to the
postgres sequence. So this approach still doesn't work.
This may be obvious, but building on my example below, the sql:
"INSERT INTO products VALUES (42,'apple','fruit');"
works perfectly, and is the sql that I expect/wish to be generated by
Rails.
Any other ideas?
Thanks!
-Cassius
Chris wrote:
> Try products[0].clone rather than creating a new object.
>
> Cassius Rosenthal wrote:
>> This is one of those questions where I knew how to do what I want to,
>> but I can't for the life of me remember how to do it. I should know
>> this, but I just can't seem to find the answer from The Brain (ie.,
>> googling didn't help).
>> Say I have a model Product. I create the table as follows:
>> [code]
>> create_table :products, :force => true do |t|
>> t.column :name, :string
>> t.column :kind, :string, :default=>"pizza"
>> end
>> [/code]
>>
>> I then load a product from a fixture:
>> [code]
>> products=YAML::load(foo.yml)
>> [/code]
>> #products[0].attributes=>
>> {:id=>"42", :name=>"apple", :kind=>"fruit"}
>> So far, so good. Note the id of 42, which is important because this
>> object relates to another model, and I want to preserve the primary
>> keys.
>>
>> Then I instantiate a new ActiveRecord from this data:
>> [code]
>> @product=Product.new(products[0].attributes)
>> [code]
>> #@products=>
>> {:id=>"1", :name=>"apple", :kind=>"pizza"}
>> Ack! ActiveRecord used the table defaults instead of the attributes
>> that I sent to the object. How do I override this behavior?
>>
>> Thanks!
>> -Cassius
>> _______________________________________________
>> talk mailing list
>> talk@phillyonrails.org
>> http://lists.phillyonrails.org/mailman/listinfo/talk
>>
>
> _______________________________________________
> talk mailing list
> talk@phillyonrails.org
> http://lists.phillyonrails.org/mailman/listinfo/talk
>
>
>
_______________________________________________
talk mailing list
talk@phillyonrails.org
http://lists.phillyonrails.org/mailman/listinfo/talk
_______________________________________________
talk mailing list
talk@phillyonrails.org
http://lists.phillyonrails.org/mailman/listinfo/talk
|
|