Active Record Associations and application outline advice

Hi if i have one model say with objects for each letter of the alphabet
e.g a,b,c … x,y,z and i want to allow users to create there own
favourite pairings of these e.g.

ab, cd, ef, gp and allow them to discuss via comments on each pairing,
whats teh best way to model this in rails?

the order of teh letters DOESNT matter so ab IS the SAME as ba. Id
rather avoid duplication in my “Pairings” table because that would mean
id have to assign user commments to both ab and ba. This would get out
of control especially if i then wanted to offer 3 letter combos e.g. abc
would also be saved as bca and cab.
This is actually my current setup but it doesnt sit well with me.

Can anyone suggest a better setup?

Sorry for the boring example of letters but it helps me write more
concisely. If you need more info id be more than happy to provide.

Adam A. wrote:

Hi if i have one model say with objects for each letter of the alphabet
e.g a,b,c … x,y,z and i want to allow users to create there own
favourite pairings of these e.g.

ab, cd, ef, gp and allow them to discuss via comments on each pairing,
whats teh best way to model this in rails?

Use a Pairing class with a polymorphic association.

the order of teh letters DOESNT matter so ab IS the SAME as ba. Id
rather avoid duplication in my “Pairings” table because that would mean
id have to assign user commments to both ab and ba.

Sort the object IDs in some unambiguous way before creating a pairing.

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Hi Thanks for your reply and your suggestions. Im a bit confused, could
you help clarify the following -

Hi if i have one model say with objects for each letter of the alphabet
e.g a,b,c … x,y,z and i want to allow users to create there own
favourite pairings of these e.g.

ab, cd, ef, gp and allow them to discuss via comments on each pairing,
whats teh best way to model this in rails?

Use a Pairing class with a polymorphic association.

I thought polymorphic associations are used when you have several
different models which have the same relationship with anohter one. I.e.
You want to have comments associated with your models for Photos, Posts
and Products for example. In this case however only my alphabet model
has a relationship with the pairings model. So im not sure how i
implement a polymorphic association here and how that that allow me to
create only one pairing record to represent ab or ba.

my current setup is
class Pairing < ActiveRecord::base
belongs_to :alphabet
belongs_to :alphabetpartner, :class_name => “Alphabet”, :foreign_key =>
“alphabetpartner_id”

class Alphabet < ActiveRecord::Base
has_many :pairings
has_many :alphabetpartners,

but this requires me to create two records in hte pairings table for ab
and ba.

the order of teh letters DOESNT matter so ab IS the SAME as ba. Id
rather avoid duplication in my “Pairings” table because that would mean
id have to assign user commments to both ab and ba.

Sort the object IDs in some unambiguous way before creating a pairing.

Can you explain more about what you mean here and are you saying that i
have to have two pairs in my pairing table for ab and ba?

No, I am saying you would not have to have two pairs. Rather, when
you construct a Pairing, pick an unambiguous way of sorting the two
Alphabet objects so that ab and ba will map to the same thing. For
example (untested):

class Pairing < AR::B
before_create do
[@alphabet, @alphabetpartner] = [@alphabet,
@alphabetpartner].sort_by {|x| [x.name, x.id]}
end
end

Marnen many thanks again for your help.
So if i sort them by their name then id, and I have A and B with ids 1
and 2 respectively then in my pairing controller id do
@pairing = Pairing.new(params[:pairing])
@pairing.save (Which would use the callback before_create above)

So A has an Ingredient_Partner B
i.e. A.alphabet_partners ===> B

But would it work the other way i.e.
B.alphabet_partners ==> A ???

i thought it wouldnt without creating a 2nd pairing with the letters
switched.

Adam A. wrote:
[…]
[…]

Use a Pairing class with a polymorphic association.

I thought polymorphic associations are used when you have several
different models which have the same relationship with anohter one. I.e.
You want to have comments associated with your models for Photos, Posts
and Products for example. In this case however only my alphabet model
has a relationship with the pairings model. So im not sure how i
implement a polymorphic association here and how that that allow me to
create only one pairing record to represent ab or ba.

On rereading, I realize I was wrong. I thought you had different
classes A-Z, but I realize now that you don’t, so that you don’t need
a polymorphic association after all.

my current setup is
class Pairing < ActiveRecord::base
belongs_to :alphabet
belongs_to :alphabetpartner, :class_name => “Alphabet”, :foreign_key =>
“alphabetpartner_id”

That looks right.

class Alphabet < ActiveRecord::Base
has_many :pairings
has_many :alphabetpartners,

but this requires me to create two records in hte pairings table for ab
and ba.

No it doesn’t.

[…]

Sort the object IDs in some unambiguous way before creating a pairing.

Can you explain more about what you mean here and are you saying that i
have to have two pairs in my pairing table for ab and ba?

No, I am saying you would not have to have two pairs. Rather, when
you construct a Pairing, pick an unambiguous way of sorting the two
Alphabet objects so that ab and ba will map to the same thing. For
example (untested):

class Pairing < AR::B
before_create do
[@alphabet, @alphabetpartner] = [@alphabet,
@alphabetpartner].sort_by {|x| [x.name, x.id]}
end
end

And BTW, @alphabetpartner should be @alphabet_partner.

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

“So A has an Ingredient_Partner B”

was a typo, should have read alphabet_partner

Adam A. wrote:

Marnen many thanks again for your help.

You’re welcome.

So if i sort them by their name then id, and I have A and B with ids 1
and 2 respectively then in my pairing controller id do
@pairing = Pairing.new(params[:pairing])
@pairing.save (Which would use the callback before_create above)

So A has an Ingredient_Partner B
i.e. A.alphabet_partners ===> B

That’s right.

But would it work the other way i.e.
B.alphabet_partners ==> A ???

i thought it wouldnt without creating a 2nd pairing with the letters
switched.

Look at the code I gave you, and think about how it would behave.
Better yet, write some tests and try it! Ask the computer, not me. :slight_smile:

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Adam A. wrote:

Thanks again.
Ok i know why your saying to have a consistent sorting method, its so as
to avoid a duplicate situation i.e. if i always sort by the letter and
id then i will always save as ab and not ba. If theres already an ab
there and i have some validations i can avoid reading in another ab.
That bit i understand.

OK.

But the problem is i will only have, and ive tested this, a one way
relationship. That is ‘A’ is an “alphabet” which has an
“alphabet_partner” of ‘b’.

I.e. a.alphabet_partner = b.

But that’s the problem, ‘B’ is just an “alphabet_partner” in this
pairing table. There is nothing in the pairing table nor the
associations currently set that say b
“B” is ALSO an “alphabet” which has an “alphabet_partner” of ‘A’.
i.e. b.alpahbet_partner == []. it will NOT yield ‘A’

Then make another association. Remember, you can have multiple
independent associations between the same pair of tables.

I have tried this with my setup and thats the result i get but also
thinking about it makes me believe this can only be the end result.

With the setup you have, you’re right. But adding one more set of
associations should solve that.

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Thanks again.
Ok i know why your saying to have a consistent sorting method, its so as
to avoid a duplicate situation i.e. if i always sort by the letter and
id then i will always save as ab and not ba. If theres already an ab
there and i have some validations i can avoid reading in another ab.
That bit i understand.

But the problem is i will only have, and ive tested this, a one way
relationship. That is ‘A’ is an “alphabet” which has an
“alphabet_partner” of ‘b’.

I.e. a.alphabet_partner = b.

But that’s the problem, ‘B’ is just an “alphabet_partner” in this
pairing table. There is nothing in the pairing table nor the
associations currently set that say b
“B” is ALSO an “alphabet” which has an “alphabet_partner” of ‘A’.
i.e. b.alpahbet_partner == []. it will NOT yield ‘A’

I have tried this with my setup and thats the result i get but also
thinking about it makes me believe this can only be the end result.

I read up and i think (im not sure though) but i think i need something
called bidirectional relationship. The only problem is I dont know how
to implement this.
Are you sure my results should be any different?

Adam A. wrote:

Hi again, thanks so much for your help i really appreciate it. I wanted
to write another association like you said before but there is no
Alphabet_Partner class to write it in. Its just a self reference to
Alphabet table.
[…]

You don’t need an AlphabetPartner class. You just need a second
association between Alphabet and Pairing on the alphabet_partner_id
column. See the docs or the associations guide for how to do this.

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Hi again, thanks so much for your help i really appreciate it. I wanted
to write another association like you said before but there is no
Alphabet_Partner class to write it in. Its just a self reference to
Alphabet table.

Alphabet_Partner is only defined in

class Alphabet < ActiveRecord::Base
belongs_to :category
has_many :pairings
has_many :alphabet_partners,
:through => :pairings

so after googling today im wondering how do i write the equivalent

of

classs Alphabet_Partner < AR:B

has_many :pairings
has_many :alphabets,:through => :pairings

The main reason why im trying to keep only one record in pairings is to
make it easier to attach comments. Under my current setup If users
comment on the pairing ab then id have to attach those comments to ba as
well. The same goes for removing comments. I cant find any tutorials
dealing with this. The only ones availalbe are for social networks and
friendships. But no one ever comments on a friendship like “Oh they make
such a lovely couple!” :wink: so im wondering how its done. And i do need
the ability to do a.alphabet_partners and b.alphabet_partners.