has_many:通过混乱

时间:2012-01-27 03:19:04

标签: ruby-on-rails associations

我一直在寻找其他问题/答案,但找不到任何有帮助的东西。我有usersevents以及static_events。我现在想为schedule引入一个users来保存两种不同类型的“事件”

我正忙着组织协会。特别是将eventsstatic_events与特定:foreign_key相关联以创建schedule。这是我的第一个应用程序,所以事情仍然有点新。一如既往,任何帮助将不胜感激。以下是我到目前为止的情况:

模型:

class User < ActiveRecord::Base
  has_many :events, :through => :schedules, :source => "followed_id"
  has_many :static_events, :through => :schedules, :source => "followed_id"
end

class Event  < ActiveRecord::Base
  belongs_to :users
  belongs_to :schedules, :foreign_key => "followed_id"
end

class StaticEvent  < ActiveRecord::Base
  belongs_to :users
  belongs_to :schedules, :foreign_key => "followed_id"
end

class Schedule  < ActiveRecord::Base
  belongs_to :users
  has_many :events
  has_many :static_events 
end

数据模式:

create_table "schedules",
 t.integer   "followed_id" 
end

create_table "users",
  t.string   "name"
  t.string   "email"
  t.datetime "created_at"
  t.datetime "updated_at"
end

create_table "events",
  t.string   "content"
  t.integer  "user_id"
  t.datetime "created_at"
  t.datetime "updated_at"
  #several more fields left out for brevity
end

create_table "static_events",
  t.string   "content"
  t.integer  "user_id"
  t.datetime "created_at"
  t.datetime "updated_at"
  #several more fields left out for brevity
end

我能以最有效的方式解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

你的代码很好。但是,您不清楚为什么有两个不同的模型EventStaticEvent。在您的迁移中,它们似乎具有相同的字段。这似乎是single-table inheritance的一个好例子。在这种情况下,您的Event模型将保持不变,但StaticEvent将如下所示:

class StaticEvent < Event
  # ...
end

它继承自Event,而不是直接来自ActiveRecord::Base。这意味着它可以获取Event的所有行为,但您也可以定义特定于StaticEvent的方法和变量。

使用单表继承,您将没有static_events表,但您的events表将有一个额外的字符串字段type。 Rails会处理剩下的事情。

然而,如果StaticEvent没有任何与Event不同的方法或变量,除了“这是一个静态的”,你不认为你'将来会有更多内容,只使用Event两者并使用布尔类型给它is_static字段会更有意义。在这种情况下,您的Schedule模型将如下所示:

class Schedule  < ActiveRecord::Base
  # ...

  has_many :events,        :conditions => { :is_static => false }

  has_many :static_events, :conditions => { :is_static => true },
                           :class_name => 'Event'
end

这样每个关联都有自己的名称(eventsstatic_events),但两者都引用相同的模型(:class_name => 'Event')。唯一的区别是条件,它指定哪些 Event记录是该关联的一部分。这也允许您免费执行Schedule.static_events.create ...Schedule.static_events.where(...).first等操作。

终于,你说你“现在想要为用户介绍一个保存两种不同类型的'事件的时间表'。”如果这是你创建{{1}的唯一原因您只需删除Schedule模型并直接在Schedule上定义上述关联。这里不需要额外的Schedule模型,除非它有自己的属性和/或方法。