Many-to-Many relationship的实际应用(1)

需求:场景如下,user可以是多个group的会员,管理者和创建者。group有1个创建者,多个管理者和多个会员。

解决方案:

建立数据库:

sql 代码
  1. CREATE TABLE `groups` (   
  2.   `id` int(11) NOT NULL auto_increment,   
  3.   `namevarchar(32) NOT NULL,   
  4.   `url` varchar(250) NOT NULL,   
  5.   `description` varchar(100) default NULL,   
  6.   `logo` int(11) NOT NULL,   
  7.   `created_time` datetime NOT NULL,   
  8.   PRIMARY KEY  (`id`)   
  9. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;   
  10.   
  11. CREATE TABLE `users` (   
  12.   `id` int(11) NOT NULL auto_increment,   
  13.   `logo` int(11) NOT NULL,   
  14.   `namevarchar(25) NOT NULL,   
  15.   `sex` int(11) NOT NULL,   
  16.   `birthday` datetime NOT NULL,   
  17.   `location` varchar(100) NOT NULL,   
  18.   `hashed_password` varchar(40) NOT NULL,   
  19.   PRIMARY KEY  (`id`)   
  20. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;   
  21.   
  22. CREATE TABLE `members` (   
  23.   `id` int(11) NOT NULL,   
  24.   `user_id` int(11) NOT NULL,   
  25.   `group_id` int(11) NOT NULL,   
  26.   `priviledge` varchar(10) default NULL,   
  27.   PRIMARY KEY  (`id`)   
  28. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;  

 注意members这个表中的priviledge属性,priviledge属性有3个选择(creator, admin, leaguer),分别代表user在group中的3种身份权限。

model代码:

ruby 代码
  1. class Member < ActiveRecord::Base   
  2.   belongs_to :group  
  3.   belongs_to :user  
  4. end  
  5.   
  6. class User < ActiveRecord::Base   
  7.   has_many :members  
  8.   has_many :groups,   
  9.     :through => :members,   
  10.     :order => "priviledge desc"  
  11. end  
  12.   
  13. class Group < ActiveRecord::Base   
  14.   has_many :members  
  15.   has_many :users,   
  16.     :through => :members  
  17.   has_many :creators,           
  18.     :through => :members,   
  19.     :source => :user,   
  20.     :conditions => ["priviledge = 'creator'"]   
  21.   has_many :admins,   
  22.     :through => :members,   
  23.     :source => :user,   
  24.     :conditions => ["priviledge = 'admin'"]   
  25.   has_many :leaguers,   
  26.     :through => :members,   
  27.     :source => :user,   
  28.     :conditions => ["priviledge = 'leaguer'"]   
  29. end  

 这里注意的是

ruby 代码
  1. has_many :creators,           
  2.     :through => :members,   
  3.     :source => :user,   
  4.     :conditions => ["priviledge = 'creator'"]  

 

不能用has_one来替代,所以替代的方法就是在Group里面加上如下代码:

ruby 代码
  1. def creator   
  2.     creators[0]   
  3. end  

这样可以使用Group#creator来得到管理员。

如下代码为测试代码:

ruby 代码
  1. group = Group.find(2)   
  2. user = User.find(1)   
  3. member = Member.create(:group_id => group, :user_id => user, :priviledge => "admin")  

你可能感兴趣的:(sql,Ruby,ActiveRecord)