Skip to content

Instantly share code, notes, and snippets.

@bokmann
Created February 26, 2012 02:38
Show Gist options
  • Save bokmann/1912350 to your computer and use it in GitHub Desktop.
Save bokmann/1912350 to your computer and use it in GitHub Desktop.
Another example for Mel...
# Mel, Here is another gist for you, perhaps slightly better than the last.
# First, the migrations are exactly the same, but this improves the left-right
# situation slightly.
# kit.rb
class Kit < ActiveRecord::Base
has_many :peer_kit_relations,
:class_name => "KitRelation",
:foreign_key => :left_kit_id
has_many :peer_kits,
:through => :peer_kit_relations,
:source => :right_kit
def associate_kit(other_kit)
peer_kits << other_kit
other_kit.peer_kits << self
end
end
# kit_relation.rb
class KitRelation < ActiveRecord::Base
belongs_to :left_kit, :class_name => "Kit"
belongs_to :right_kit, :class_name => "Kit"
end
# exercising from rails console
k1 = Kit.create(:name => "First Kit")
k2 = Kit.create(:name => "Second Kit")
k3 = Kit.create(:name => "Third Kit")
# Note that this works:
k1.peer_kits << k2
# but the problem is the relationship goes one way only - so while k2
# is in k1's peer list, k1 is not in k2's peer list. This means every
# time you have to do this:
k1.peer_kits << k2
k2.peer_kits << k1
# To help with that, there is the associate_kit method:
k1.associate_kit(k2)
# I still consider that an ugly solution.
# There should be a way to push knowledge of this bi-directional
# 2-record creation into the peer_kit_relations, using something
# like a block passed to the relationship:
has_many :peer_kit_relations,
:class_name => "KitRelation",
:foreign_key => :left_kit_id do
# some kind of magic goes in this block
end
@bokmann
Copy link
Author

bokmann commented Feb 26, 2012

And one last disgusting thought -

Using the same tables, we could have the kit maintain a left_kits and a right kits just like the previous gist, but then create a custom view with a migration using straight sql something like:

create view peer_kits as
select left_kit_id, right_kit_id
from kit_relations
union
select right_kit_id, left_kit_id
from kit_relations

and then in the kit, define a method like this:

def peer_kits
find_by_sql "select * from kits where id in (select right_kit_id from peer_kits where left_kit_id = #{id})"
end

This would be more like the first solution, except the really heinous peer_kits method in ruby is pushed to a view and custom sql. I'm too tired to give that a shot at the moment...

@bokmann
Copy link
Author

bokmann commented Feb 26, 2012

Ok, I lied - I wasn't too tired to try it. I'm posting the new code to the old gist over at https://gist.github.com/1912278

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment