On Nov 24, 1:50 am, Jesús Gabriel y Galán <[email protected]>
wrote:
> On Thu, Nov 24, 2011 at 3:08 AM, Jeremy Evans <[email protected]> wrote:
> > On Nov 21, 8:44 am, Jesús Gabriel y Galán <[email protected]>
> > wrote:
> >> Hi,
>
> >> I have a many to many association in which the join table has
> >> additional columns. I'm modeling a deck management application for
> >> Magic the Gathering, and I have the following tables:
>
> >> DB.create_table(:mtg_database) do
> >>         Integer :gatherer_id
> >>         primary_key [:gatherer_id]
>
> > You can probably just use "primary key :gatherer_id" here
>
> I understood this would create an autoincrementing column, whereas I
> want to set the id myself, because it comes from an external system.

Ah, I didn't appreciate that distinction.  You could do:

  Integer :gatherer_id, :primary_key=>true

> >  deck_card_dataset.filter(:gatherer_id =>
> > card.gatherer_id).update(:qty=>:qty+1)
>
> OK, you mean to do this in the else part of the check right?

No, in the if part of the check.  The else part (which does the
create), is fine, though you could remove the :qty=>1 if you make that
the default.

> I mean I need to do different things for the first insertion and the
> subsequent ones,
> and I understand this statement needs that the row in the deck_card
> table already exists, correct?

Yes, but you are still checking for existance in the if statement.

> If so, wouldn't there still be a race condition?

Yes, there is in the sense that if two processes/threads attempt to
create at the same time.  However, the primary key constraint in the
deck_card table will prevent that, so an error would be raised by one
of the processes/threads in that case.

> def add_card_to_deck card
>   deck_card = deck_card card
>   if deck_card
>     deck_card_dataset.filter(:gatherer_id =>
> card.gatherer_id).update(:qty=>:qty+1)
>   else
>     DeckCard.create({:card => card, :deck => self, :qty => 1})
>   end
> end
>
> Or am I misunderstanding and you meant a different thing?

That's basically right.

> >> 3.- I had to add the unrestrict_primary_key in the Card model. Until I
> >> did, I wasn't able to create cards setting the gatherer_id, which is
> >> an external id that I want to have as pk of that table. Am I doing
> >> something wrong? I'm creating Cards like this:
>
> > It should only affect mass assignment (which create uses).  There's
> > nothing wrong with it, though you have to be more careful with user
> > input if you unrestrict access to the primary key.
>
> OK, but my question is why is that needed when the PK is not an
> autoincrementing id?

If the primary key is not autoincrementing, then you are more likely
to want unrestricted access to it.  However, Sequel defaults to
restricted access for all primary keys, not just those that are
autoincrementing.

> If I need to build a model in which I need to setup the id myself when
> creating, as is my case, what should I do?

Using unrestrict_primary_key is fine.  Just be careful with user
input.

> Is this the recommended way? Until I add that line I was getting
> errors when I tried to set the gatherer_id in a Card object.

There's no problem with enabling unrestricted access.  The alternative
in your case would be to call the setter method manually:

  Model.create(hash){|m| m.primary_key = ...}

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.

Reply via email to