2011-09-06 83 views
4

我剛剛開始使用DataMapper,並試圖找出爲什麼您需要指定hasbelongs_toDataMapper - 爲什麼「有」和「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 

回答

6

只有當您要使用由額外規範生成的方法時,才指定關係的兩側。它是完全可選的:如果您從不需要從Comment(例如@comment.post)到Post,您將不必在Comment中指定belongs_to關係。

一個好處是你的實例有點清潔,因爲在Comment附加的方法不會自動生成。另一方面,如果你需要它們,那些額外的方法不會打擾你。請參閱documentation about associations in ActiveRecord

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添加到用戶。這也沒有意義,它也不會工作,因爲缺乏數據庫列在那裏。當通過選項存在時,這當然可以被調整,但是當不需要時,這會再次提高代碼的複雜度。大安在他的回答中說,你不需要兩者都可以工作,這是可選的。

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 

如果使用內Posthas n, :comments,但選擇不包括內Commentbelongs_to :post,在commentspost_id列仍將被創建並建立索引,但不會添加外鍵約束。

相關問題