DataMapper - 为什么“has”和“belongs_to”?

时间:2011-09-06 15:44:24

标签: ruby sinatra ruby-datamapper

我刚刚开始使用DataMapper,我正在试图弄清楚为什么需要指定hasbelongs_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

3 个答案:

答案 0 :(得分:7)

仅当您要使用额外规范生成的方法时,才指定关系的两侧。它完全是可选的:如果您永远不需要从Post(例如Comment)转到@comment.post,则无需在{{belongs_to中指定Comment关系1}}。

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

另请参阅documentation about associations in ActiveRecord

答案 1 :(得分:0)

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

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

例如:

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

RolesUser是一个连接表,对于用户和角色模型都具有belongs_to。在这种情况下隐含所属将然后将belongs_to添加到用户的角色模型。这也没有意义,由于缺乏数据库专栏,它也无法工作。当然,当有贯穿选项时,这可以调整,但是当不需要时,这将极大地提高代码的复杂性。正如Daan在他的回答中所说,你不需要两者都可以工作,这是可选的。

答案 2 :(得分:0)

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

e.g:

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, :comments中使用Post,但选择不在belongs_to :post中添加Commentpost_id表格中的comments列将会仍然可以创建和索引,但不会添加外键约束。