Re: Problems with reciprocal assignation (and others...)

2018-03-05 Thread Jeremy Evans
On Monday, March 5, 2018 at 12:18:42 PM UTC-8, da...@abstra.cc wrote:
>
> b2.foo = f2
>> # raises Sequel::Error: associated object # does not have 
>> a primary key
>>
>> After fixing those issues, let's consider f3.bars.  f3 is basically just 
>> Foo[1], since b3.foo_id is 1.  Foo[1].bars doesn't return [f2], it returns 
>> [b2]. It should never return f2 or f3 because it returns instances of Bar, 
>> not of Foo.  If you are asking if f3.bars should return [b2, b3], no, 
>> because b3 hasn't been saved to the database yet.
>>
>
>  I think reciprocal is a good concept, but I don't understand why it works 
> in some cases and not in others. Loos at the first example. A simple f.bars 
> before b2.foo = f2 assignment resolves well the reciprocal. But if you do 
> without first loading bars, reciprocal assignation is avoided. It doesn't 
> depend of persisted objects. 
>

That's correct, if you have code like:

f2 = Foo.create
b2 = Bar.new
f2.bars
b2.foo = f2
f2.bars
# => [b2]

then f2.bars returns b2 even though b2 hasn't been persisted yet, because 
an association modification method was called on the reciprocal object 
(b2.foo=).
 

> Second case is, pehaps, subtle, but I think the object representation 
> (with reciprocals) doesn't depend in Sequel of persisted state, but in this 
> case it seems so.
>

The difference in the b3 case is that an association modification method is 
not called, only an association retrieval method.  Association retrieval 
methods don't modify existing reciprocals, since they return new objects, 
and only set the reciprocal object in the returned object in certain cases, 
most commonly when you do:

foo = Foo[1]
foo.bars.each |bar|
  bar.foo # already set
end

The many_to_one association doesn't generally set reciprocals on returned 
objects.  When you do:

f3 = b3.foo
# f3.bars not already set

f3.bars cannot be set in such a case, because you don't actually know which 
bars are associated to f3 without doing a query.  You seem to want to 
Sequel to do the query to get the bars for f3, and then after the query, 
add b3 to the results because it was the object used to retrieve f3.  
That's not how Sequel works, and I'm not sure the behavior is desirable.  
It is probably something you could do in a custom plugin, so I would go 
down that route if that is the behavior you want.

Thanks,
Jeremy

-- 
You received this message because you are subscribed to the Google Groups 
"sequel-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sequel-talk+unsubscr...@googlegroups.com.
To post to this group, send email to sequel-talk@googlegroups.com.
Visit this group at https://groups.google.com/group/sequel-talk.
For more options, visit https://groups.google.com/d/optout.


Re: Problems with reciprocal assignation (and others...)

2018-03-05 Thread david


El lunes, 5 de marzo de 2018, 20:55:40 (UTC+1), Jeremy Evans escribió:
>
> On Monday, March 5, 2018 at 9:00:38 AM UTC-8, David wrote:
>>
>> Hi everybody.
>>
>> Look at this code:
>>
>> class Foo < Sequel::Model
>>   one_to_many :bars
>> end
>>
>> class Bar < Sequel::Model
>>   many_to_one :foo
>> end
>>
>> f = Foo.new
>> b = Bar.new
>> b.foo = f
>> f.bars # => []
>>
>> f2 = Foo.new
>> b2 = Bar.new
>> f.bars # Magic line!
>> b2.foo = f2
>> f2.bars# => [b2]
>>
>>
>> I think first case should return same that second case.
>>
>> We continue with the example:
>>
>> f2.save# Foo object with id 1 and a bar child
>>
>> b3 = Bar.new(foo_id: 1)
>> f3 = b3.foo
>> f3.bars# => [f2]
>>
>>
>> In this case, I think it should return [f2, f3]
>>
>> Do you see these requirements logical? If we have reciprocal and object
>> assignation, I think these are two annoying Sequel effects that go against
>> "least surprise" principle.
>>
>
> No, I don't think this makes sense.  First, your example has errors:
>

Arggg!

I am so sorry for the errors. I refer to [b2, b3], as you point.

b2.foo = f2
> # raises Sequel::Error: associated object # does not have 
> a primary key
>
> After fixing those issues, let's consider f3.bars.  f3 is basically just 
> Foo[1], since b3.foo_id is 1.  Foo[1].bars doesn't return [f2], it returns 
> [b2]. It should never return f2 or f3 because it returns instances of Bar, 
> not of Foo.  If you are asking if f3.bars should return [b2, b3], no, 
> because b3 hasn't been saved to the database yet.
>

 I think reciprocal is a good concept, but I don't understand why it works 
in some cases and not in others. Loos at the first example. A simple f.bars 
before b2.foo = f2 assignment resolves well the reciprocal. But if you do 
without first loading bars, reciprocal assignation is avoided. It doesn't 
depend of persisted objects.

Second case is, pehaps, subtle, but I think the object representation (with 
reciprocals) doesn't depend in Sequel of persisted state, but in this case 
it seems so.

Thank you very much, and sorry again for errors :(

-- 
David

-- 
You received this message because you are subscribed to the Google Groups 
"sequel-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sequel-talk+unsubscr...@googlegroups.com.
To post to this group, send email to sequel-talk@googlegroups.com.
Visit this group at https://groups.google.com/group/sequel-talk.
For more options, visit https://groups.google.com/d/optout.


Re: Problems with reciprocal assignation (and others...)

2018-03-05 Thread Jeremy Evans
On Monday, March 5, 2018 at 9:00:38 AM UTC-8, da...@abstra.cc wrote:
>
> Hi everybody.
>
> Look at this code:
>
> class Foo < Sequel::Model
>   one_to_many :bars
> end
>
> class Bar < Sequel::Model
>   many_to_one :foo
> end
>
> f = Foo.new
> b = Bar.new
> b.foo = f
> f.bars # => []
>
> f2 = Foo.new
> b2 = Bar.new
> f.bars # Magic line!
> b2.foo = f2
> f2.bars# => [b2]
>
>
> I think first case should return same that second case.
>
> We continue with the example:
>
> f2.save# Foo object with id 1 and a bar child
>
> b3 = Bar.new(foo_id: 1)
> f3 = b3.foo
> f3.bars# => [f2]
>
>
> In this case, I think it should return [f2, f3]
>
> Do you see these requirements logical? If we have reciprocal and object
> assignation, I think these are two annoying Sequel effects that go against
> "least surprise" principle.
>

No, I don't think this makes sense.  First, your example has errors:

b2.foo = f2
# raises Sequel::Error: associated object # does not have a 
primary key

After fixing those issues, let's consider f3.bars.  f3 is basically just 
Foo[1], since b3.foo_id is 1.  Foo[1].bars doesn't return [f2], it returns 
[b2]. It should never return f2 or f3 because it returns instances of Bar, 
not of Foo.  If you are asking if f3.bars should return [b2, b3], no, 
because b3 hasn't been saved to the database yet.

Thanks,
Jeremy

-- 
You received this message because you are subscribed to the Google Groups 
"sequel-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sequel-talk+unsubscr...@googlegroups.com.
To post to this group, send email to sequel-talk@googlegroups.com.
Visit this group at https://groups.google.com/group/sequel-talk.
For more options, visit https://groups.google.com/d/optout.


Problems with reciprocal assignation (and others...)

2018-03-05 Thread david
Hi everybody.

Look at this code:

class Foo < Sequel::Model
  one_to_many :bars
end

class Bar < Sequel::Model
  many_to_one :foo
end

f = Foo.new
b = Bar.new
b.foo = f
f.bars # => []

f2 = Foo.new
b2 = Bar.new
f.bars # Magic line!
b2.foo = f2
f2.bars# => [b2]


I think first case should return same that second case.

We continue with the example:

f2.save# Foo object with id 1 and a bar child

b3 = Bar.new(foo_id: 1)
f3 = b3.foo
f3.bars# => [f2]


In this case, I think it should return [f2, f3]

Do you see these requirements logical? If we have reciprocal and object
assignation, I think these are two annoying Sequel effects that go against
"least surprise" principle.

Greets.

--
David

-- 
You received this message because you are subscribed to the Google Groups 
"sequel-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sequel-talk+unsubscr...@googlegroups.com.
To post to this group, send email to sequel-talk@googlegroups.com.
Visit this group at https://groups.google.com/group/sequel-talk.
For more options, visit https://groups.google.com/d/optout.