建立这种关系的有效方法是什么?

时间:2014-01-16 10:44:45

标签: ruby-on-rails ruby database-design

我正在尝试创建一个Web应用程序来组织用户的电视兴趣,为此,我需要存储三种类型的数据:ShowsSeasonsEpisodes

我想查询我的数据:Show.find(1).season(2).episode.each。这应该使用id返回节目第二季的每一集.1。如何设置我的模型以达到此目的?

我已尝试在season_id上使用show_idepisodes的值,但无法找到属于每个episodes的{​​{1}}。

3 个答案:

答案 0 :(得分:1)

阅读guides可能是个好主意。假设您的实体关系看起来像这样:

erd

您可以轻松地使用activerecord实现此功能。模型看起来像这样:

require 'active_record'

class Show < ActiveRecord::Base
    has_many :seasons
end

class Season < ActiveRecord::Base
    belongs_to :show
    has_many :episodes
end

class Episode < ActiveRecord::Base
    belongs_to :season
end

您的迁移可能如下所示:

require 'active_record'

class CreateShows < ActiveRecord::Migration
    def change
        create_table :shows do |t|
            t.timestamps
        end
    end
end

class CreateSeasons < ActiveRecord::Migration
    def change
        create_table :seasons do |t|
            t.references :show, :null => false
            t.timestamps
        end
    end
end

class CreateEpisodes < ActiveRecord::Migration
    def change
        create_table :episodes do |t|
            t.references :season, :null => false
            t.timestamps
        end
    end
end

将一些数据放入数据库并使用以下命令查询:

Show.find(1).seasons.first.episodes.each{ |e| puts e.title }

答案 1 :(得分:1)

以模式定义关系,

Show
 has_many :seasons

Season
 has_many :episodes
 belongs_to :show

Episode
 belongs_to :season

然后你可以这样打电话,

Show.find(1).seasons.first.episodes.each {}

答案 2 :(得分:1)

上面的答案很棒;我会更进一步,在Show模型中使用has_many的:through 选项,在Episode模型中使用 has_one:through

# Show

has_many :seasons
has_many :episodes, through: :seasons

# Season

belongs_to :show
has_many   :episodes

# Episode

belongs_to :season
has_one    :show, through: :season

这可以让您进行如下调用:

Show.first.episodes
Episode.first.show

...并且还允许您编写一些查询最小化范围,并编写简化查找相关信息的委托方法。

# Episode
delegate   :name, to: :show, prefix: :show

Episode.first.show_name # => Episode.first.show.name