4

我刚刚开始使用 DataMapper,我试图弄清楚为什么你需要指定 ahas和 a belongs_to

例如,查看 DataMapper 网站上的示例。这不是多余的吗?如果发表has n评论,那么评论不会自动belongs_to发布吗?为什么我必须指定这个?

class Post
  include DataMapper::Resource

  property :id, Serial

  has n, :comments
end

class Comment
  include DataMapper::Resource

  property :id,     Serial
  property :rating, Integer

  belongs_to :post  # defaults to :required => true

  def self.popular
    all(:rating.gt => 3)
  end
end
4

3 回答 3

7

仅当您要使用由额外规范生成的方法时,才指定关系的双方。它是完全可选的:如果您永远不需要PostComment(例如@comment.post)访问,您将不必在 中指定belongs_to关系Comment

一个优点是您的实例更干净一些,因为在Comment其他方法中不会自动生成。另一方面,如果您需要它们,那些额外的方法不会打扰您。

另请参阅ActiveRecord 中有关关联的文档

于 2011-09-06T16:00:18.943 回答
0

这为您提供了轻松访问关系对象的方法。比如@post.comments @comment.post。我明白你的意思,应用has_many 可能意味着belongs_to。尽管考虑到添加belongs_to 的开发人员开销,但可能比添加更多系统开销以动态地将方法添加到正确的类更好。

另一件事是通过另一个 has_many 关系使用 has_many 关系。这会导致奇怪的belong_to 关系,并且可能会导致SQL 出现问题。

例如:

class User < ActiveRecord::Base
  has_many :roles, :through => :roles_users
  has_many :roles_users
end

RolesUser 是一个连接表,其中包含用户和角色模型的 belongs_to。在这种情况下,暗示属于会向用户添加一个属于角色模型的 belongs_to。这也没有任何意义,由于缺少数据库列,它也不起作用。当然,当存在 through 选项时,可以对其进行调整,但是当不需要时,这又会大大提高代码的复杂性。正如 Daan 在他的回答中所说,你不需要两者都可以工作,它是可选的。

于 2011-09-06T16:03:44.770 回答
0

我想补充一下这些好的答案,如果您需要dm-constraints(直接或通过data_mapper)并使用auto_migrate!,那么belongs_to将在数据库级别自动添加外键约束,而has单独不会这样做。

例如:

require 'data_mapper'

class Post
  include DataMapper::Resource
  property :id, Serial
end

class Comment
  include DataMapper::Resource
  property :id, Serial

  belongs_to :post
end

产生这个(通过 MySQL 适配器):

 ~ (0.140343) CREATE TABLE comments (id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
post_id INT(10) UNSIGNED NOT NULL, PRIMARY KEY(id)) ENGINE = InnoDB
CHARACTER SET utf8 COLLATE utf8_general_ci

 ~ (0.234774) CREATE INDEX index_comments_post ON comments (post_id)

 ~ (0.433988) ALTER TABLE comments ADD CONSTRAINT comments_post_fk
FOREIGN KEY (post_id) REFERENCES posts (id) ON DELETE NO ACTION ON UPDATE NO ACTION

如果使用has n, :commentswithinPost但选择不包含belongs_to :postwithin Comment,表post_id中的列comments仍然会被创建和索引,但不会添加外键约束。

于 2013-09-27T11:42:33.573 回答