Rails Models Relations
Привет коллеги разработчики! Недавно я играл с Rails 3.0, и после долгих исследований я немного застрял. Я хочу знать, какой подход или решение является лучшим в моем случае (я пока не смог найти ответ). Так что я пытаюсь достичь просто и прямо.
Я хочу сделать что-то вроде этого:
class User < ActiveRecord::Base
has_many :feeds
has_many :casts, :through => :feeds
end
class Feed < ActiveRecord::Base
has_many :users
has_many :casts
end
class Cast < ActiveRecord::Base
belongs_to :feed
end
Поэтому в конце мне нужно иметь методы, такие как User.first.feeds, чтобы получить все пользовательские фиды и User.first.casts, чтобы получить все пользовательские трансляции через его / ее фиды. Также было бы неплохо иметь Feed.first.casts и Feed.first.users. Довольно просто, правда, но мне также трудно создавать миграции для того, чего я пытаюсь достичь.
Я знаю, что приведенный выше код не будет работать - я играл с ним, так что это просто концепция того, чего я пытаюсь достичь.
В основном, мои вопросы таковы: должен ли я сделать это с помощью модели соединения или использовать области?(Также не могли бы вы дать фрагмент кода) и как мне выполнить миграцию для этого?
Спасибо, и извините, я не смог найти много информации в Интернете относительно этого простого случая.
Изменить: has_and_belongs_to_many для пользователя и Feed не будет работать в моем случае, потому что он не позволяет мне иметь @user.casts, он дает только @user.feeds и @ feed.users
2 ответа
То, что вы хотите, это отношения "многие ко многим" между пользователем и фидом.
Вы захотите, чтобы что-то подобное было в вашем коде, чтобы отношения между пользователем и фидом работали.
class User < ActiveRecord::Base
has_and_belongs_to_many :feeds
end
class Feed < ActiveRecord::Base
has_and_belongs_to_many :users
end
Подробнее об этом вы можете прочитать в Руководстве по Rails - http://guides.rubyonrails.org/association_basics.html
Вы также можете посмотреть на использование has_many:through с промежуточной моделью для этого (объяснение здесь http://guides.rubyonrails.org/association_basics.html), если вы захотите нравится хранить любые метаданные для записи отношений с фидом пользователей.
Редактировать: мне удалось получить аналогичную настройку, работающую на 3.0, а также 3.1 (используя has_many:through).
Вот содержимое моих моделей.
➜ app cat app/models/*
class Cast < ActiveRecord::Base
belongs_to :feed
end
class Feed < ActiveRecord::Base
has_many :subscriptions
has_many :casts
end
class Subscription < ActiveRecord::Base
belongs_to :user
belongs_to :feed
end
class User < ActiveRecord::Base
has_many :subscriptions
has_many :feeds, :through => :subscriptions
# For 3.1
has_many :casts, :through => :feeds
# For 3.0
def casts
Cast.joins(:feed => :subscriptions).where("subscriptions.user_id" => self.id)
end
end
и вот миграции, которые я использовал
➜ app cat db/migrate/*
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.string :name
t.timestamps
end
end
def self.down
drop_table :users
end
end
class CreateFeeds < ActiveRecord::Migration
def self.up
create_table :feeds do |t|
t.string :name
t.timestamps
end
end
def self.down
drop_table :feeds
end
end
class CreateCasts < ActiveRecord::Migration
def self.up
create_table :casts do |t|
t.string :name
t.integer :feed_id
t.timestamps
end
end
def self.down
drop_table :casts
end
end
class CreateSubscriptions < ActiveRecord::Migration
def self.up
create_table :subscriptions do |t|
t.integer :feed_id
t.integer :user_id
end
end
def self.down
drop_table :subscriptions
end
end
В http://railscasts.com/episodes/265-rails-3-1-overview Райан Бейтс говорит, что rails 3.1 поддерживает цепочку has_many: посредством вызовов. Это не возможно в 3.0