新手问题 many-to-many 关联

tsinghan · 2013年12月07日 · 最后由 knwang 回复于 2013年12月08日 · 2595 次阅读

比如 user 和 team 是多对多关联

class User < ActiveRecord::Base
  has_many  :team_users
  has_many  :teams, :through => :team_users
end
class Team < ActiveRecord::Base
  has_many  :team_users
  has_many  :users, :through => :team_users
end
class TeamUser < ActiveRecord::Base
  belongs_to :user
  belongs_to :team
end

在给 user 设置多个 team 的时候,想给用户设置一个默认的 team,是不是要在 team_users 中间表里面增加一个字段 status 来标示?如果是这样的话,保存的时候,

user.teams << teams 

status 怎么保存?

TeamUser.create(user_id:xx,team_id:xx,status:xx) 单独存?

中间表有其他信息的单独建 model。即使没有其他信息我也单独建 model,并且加主键。

#2 楼 @hooopo 没理解什么意思,能否举个例子?

#3 楼 @TsingHan 可以给 user 增加一个外键,如 team_id,设置其默认的组。

#2 楼 @hooopo 你这样做有啥好处?对象关系岂不是对象关系上更模糊了?

#4 楼 @mingyuan0715 恩 这也是一种办法哈

#5 楼 @fengkuok 查询的时候可以不一定使用 join,可以拆分成一个 select 和一个 in 查询。修改关系的时候也更灵活。添加额外信息的时候更方便。。

#7 楼 @hooopo 恩,我记得很久前遇到过这种关系上有额外属性的情况,但是现在竟然想不到一个这种例子了=_=

join 的话确实属于数据库体力活儿,in 也差不太多,直接刷缓存的话最理想

嗯 在 TeamUser 里增加个 status 字段,这样 TeamUser 不只是一个简单的关联表,也有业务字段;这个情况应该还是蛮常见的。

这个好像只有自己写方法来实现

def set_default_team(team)
    self.team_users.create(team_id:team.id, status:1)
end

def get_default_team
    self.team_users.where(status:1).team
end

这样之类的

在 user 里加一个 default_team_id 字段比较好 毕竟关联表应该只是表达了从属关系 应该叫 Membership

好的代码,模型和数据库的设计一定是业务驱动,而不是技术或者框架驱动,再用代码或者文档在业务层和代码层搭桥。

在这个例子里面,与其想 Rails 的 convention 在这种情况下写?不如想在真实的情况下,你管这个东西叫什么?如果你在多个球队,你和每个球队的关联叫什么?你肯定不会说, "Oh, 我的这个 TeamUser 过期了!",这样想那么 Membership 这个 model 就很明显了。而一旦你叫了这个 model Membership, 很多东西比如 membership status, membership expiration date, membership fee due date 这些就都有地方放了。

http://martinfowler.com/bliki/UbiquitousLanguage.html

需要 登录 后方可回复, 如果你还没有账号请 注册新账号