On Nov 30, 6:10 pm, Will Leinweber <[email protected]> wrote:
> Let's go with the example from the docs
>
> class Project < Sequel::Model
> many_to_one :portfolio
> end
>
> I would like to create a new portfolio, set some things on it from my
> project then when I save project, create the portfolio if necessary
> and save it.
>
> def some_method_in_project
> self.portfolio = Portfolio.new # this blows up :(
> portfolio.name = 'something'
> self.save # create portfolio if necessary in before_save callback
> for me
> end
>
> However, due to
>
> def set_associated_object(opts, o)
> raise(Error, "associated object #{o.inspect} does not have a
> primary key") if o && !o.pk
>
> in model/associations.rb, the portfolio must have already been
> created, which seems like a limitation.
This is by design. portfolio= needs to set the portfolio_id based on
the primary key of the Portfolio object. The object you are passing
to portfolio= does not have a primary key, so you get an error.
You may be used to ActiveRecord, which has much more "magical"
associations than Sequel. Sequel associations are specifically
designed to be simple and easier to understand and reason about (they
do not use proxies at all).
> Is there any way around this? Or do I have to create the portfolio,
> and in a rescue somewhere destroy the timeline if the save or
> validation or anything fails?
There are multiple ways around this. The simplest way is just to save
the Portfolio first. Assuming you do the Portfolio save and the
Project save in the same transaction, you shouldn't need any special
rescue code, the transaction will just rollback.
The other way is to use the nested_attributes plugin:
self.portfolio_attributes = {:name=>'something'}
or the instance_hooks plugin (which the nested attributes plugin uses
internally):
before_save_hook{self.portfolio =
Portfolio.create(:name=>'something')}
The nested attributes plugin offers a slightly nicer API, and
integrates the validations (so a validation failure for Portfolio will
cause a validation failure for the Project).
Which of these approaches is best for your app depends on your app's
needs and your personal preference.
Jeremy
--
You received this message because you are subscribed to the Google Groups
"sequel-talk" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sequel-talk?hl=en.