Skip to content

Instantly share code, notes, and snippets.

@werelax
Created September 18, 2011 18:02
Show Gist options
  • Save werelax/1225330 to your computer and use it in GitHub Desktop.
Save werelax/1225330 to your computer and use it in GitHub Desktop.
First try with ternary associations with ActiveRecord
require 'active_record'
require 'sqlite3'
ActiveRecord::Base.establish_connection(
:adapter => 'sqlite3',
:database => ':memory:'
)
ActiveRecord::Schema.define do
create_table :users do |t|
t.column :name, :string
end
create_table :tags do |t|
t.column :name, :string
end
create_table :favs do |t|
t.column :url, :string
end
create_table :user_fav_tags do |t|
t.column :user_id, :integer
t.column :tag_id, :integer
t.column :fav_id, :integer
end
end
class UserFavTag < ActiveRecord::Base
class << self
def add_fav_with_tags(user, url, tag_names)
fav = Fav.find_or_create_by_url(:url => url)
tag_names.each do |name|
tag = Tag.find_or_create_by_name(name)
self.create(:user_id => user.id, :tag_id => tag.id, :fav_id => fav.id)
end
end
end
belongs_to :user
belongs_to :fav
belongs_to :tag
end
class User < ActiveRecord::Base
has_many :user_fav_tags
has_many :tags, :through => :user_fav_tags
has_many :favs, :through => :user_fav_tags
def add_fav_with_tags(url, tags)
UserFavTag.add_fav_with_tags(self, url, tags)
end
end
class Tag < ActiveRecord::Base
has_many :user_fav_tags
has_many :users, :through => :user_fav_tags
has_many :favs, :through => :user_fav_tags
end
class Fav < ActiveRecord::Base
has_many :user_fav_tags
has_many :users, :through => :user_fav_tags
has_many :tags, :through => :user_fav_tags
end
u = User.create(:name => 'pepito')
u.add_fav_with_tags('http://www.google.com', ['tag1', 'tag2'])
u.add_fav_with_tags('http://www.yahoo.com', ['tag2', 'tag3'])
# Output
#
# ruby-1.9.2-p290 :001 > load 'test.rb'
# ruby-1.9.2-p290 :002 > u = User.first
# => #<User id: 1, name: "pepito">
# Duplicados! Los id's aparecen varias veces en user_fav_tags
# ruby-1.9.2-p290 :003 > u.tags
# => [#<Tag id: 1, name: "tag1">, #<Tag id: 2, name: "tag2">, #<Tag id: 2, name: "tag2">, #<Tag id: 3, name: "tag3">]
# ruby-1.9.2-p290 :004 > u.favs
# => [#<Fav id: 1, url: "http://www.google.com">, #<Fav id: 1, url: "http://www.google.com">, #<Fav id: 2, url: "http://www.yahoo.com">, #<Fav id: 2, url: "http://www.yahoo.com">]
# Para filtrarlos:
# ruby-1.9.2-p290 :006 > u.tags.find(:all, :group => 'id')
# => [#<Tag id: 1, name: "tag1">, #<Tag id: 2, name: "tag2">, #<Tag id: 3, name: "tag3">]
# ruby-1.9.2-p290 :007 > u.favs.find(:all, :group => 'id')
# => [#<Fav id: 1, url: "http://www.google.com">, #<Fav id: 2, url: "http://www.yahoo.com">]
# O también (no se cuál será más rápido):
# ruby-1.9.2-p290 :008 > u.tags.uniq
# => [#<Tag id: 1, name: "tag1">, #<Tag id: 2, name: "tag2">, #<Tag id: 3, name: "tag3">]
# ruby-1.9.2-p290 :009 > u.favs.uniq
# => [#<Fav id: 1, url: "http://www.google.com">, #<Fav id: 2, url: "http://www.yahoo.com">]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment