我刚刚开始使用DataMapper,我正在试图弄清楚为什么需要指定has
和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
答案 0 :(得分:7)
仅当您要使用额外规范生成的方法时,才指定关系的两侧。它完全是可选的:如果您永远不需要从Post
(例如Comment
)转到@comment.post
,则无需在{{belongs_to
中指定Comment
关系1}}。
一个优点是您的实例更清晰,因为在Comment
中,其他方法不会自动生成。另一方面,如果你需要它们,那些额外的方法不会打扰你。
答案 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
中添加Comment
,post_id
表格中的comments
列将会仍然可以创建和索引,但不会添加外键约束。