Rails多对一关联

时间:2012-01-02 03:34:06

标签: ruby-on-rails associations

您好我是rails的新手,并开始使用一个简单的应用程序,该应用程序包含许多“任务”,每个应用程序都附带一个“标记”。所以关系就像 - 许多'任务'都有一个/同一个'标签'。我如何在我的模型中提出这个问题。我尝试使用'task'has_one'tag'和'tag'edela_to''task'规则,但它仅适用于带有该标签的第一个'任务',以及带有相同'tag'的其他'任务'它不会起作用。请建议我正确的方法。谢谢:))

class Task < ActiveRecord::Base
  has_many :logs
  has_one :tag , :foreign_key => "id"
end

class Tag < ActiveRecord::Base
  belongs_to :task
end

3 个答案:

答案 0 :(得分:10)

在我看来,你已经转过身来了 - 我见过的Rails的每个新手都在他们的第一个项目中做到了这一点。

你想要的是

class Task < ActiveRecord::Base
  has_many :logs
  belongs_to :tag
end

class Tag < ActiveRecord::Base
  has_many :tasks
end

以这种方式思考 - 如果单击某个标记,您可能会看到包含该标记的所有任务的列表。因此标签有很多任务,每个任务都属于一个标签。这与您描述项目的方式相符。 Has_one旨在用于一对一关系,其中每个任务都有自己唯一的标记。

答案 1 :(得分:2)

您的问题可能是使用外键“id”表示您使用Tags表“ids”列作为键,这是不合逻辑的。在这种情况下,id为1的Task认为它将与id为1的Tag相关联。

如果您使用RAILs约定设置迁移,我会假设您在tags表中有一个记录task_id的列。在这种情况下,我认为您只需要这些关联:

 class Task < ActiveRecord::Base
   has_many :logs
   has_one :tag
 end

 class Tag < ActiveRecord::Base
   belongs_to :task
 end

同样,这将假设您有一个名为“task_id”的标签属性。如果您将其保存在非常规密钥中,例如“custom_name_task_id”,则会更改为

 class Task < ActiveRecord::Base
   has_many :logs
   has_one :tag, :foreign_key => "custom_name_task_id"
 end

 class Tag < ActiveRecord::Base
   belongs_to :task
 end

答案 2 :(得分:1)

如果我理解正确,那么您希望任务只有一个标记,但该标记可以属于多个任务,则关联是向后的。您需要在任务中使用belongs_to :tag,在标记中使用has_many :tasks

但是,我认为你最终可能会想要一个任务的多个标签,我认为从一开始就做M-M关系会更好,就像这样:

class Task < ActiveRecord::Base
  has_many :tagged_tasks
  has_many :tags, through: :tagged_tasks
end

class Tag < ActiveRecord::Base
  has_many :tagged_tasks
  has_many :tasks, through: :tagged_tasks
end

class TaggedTask < ActiveRecord::Base
  belongs_to :task
  belongs_to :tag
end

这允许您为任务创建多个标记,但您可能只需使用acts_as_taggable_on gem,它就能为您完成所有这些。