2013-05-13 25 views
0

我已經實現了用戶組關係的模型,其中一個用戶可以是一個或多個組的成員和所有者,並且其中一個組可以擁有一個或多個所有者和一個或多個成員。Ruby/DataMapper:多個多對多關聯的問題

現在,問題是User.owned_groups只返回1組,即使用戶擁有多個組。

我面臨與User.member_groups,Group.ownersGroup.members相同的問題。所有方法都只返回1條記錄。

下面是數據庫中的模型和值。

型號: -

require 'rubygems' 
require 'data_mapper' 
require 'dm-types' 

module Contacts 
    class User 
    include DataMapper::Resource 

    property :id,   Serial, :key => true 
    property :username, String, :required => true, :unique => true 

    has n, :group_owners, :child_key => [:owned_group_id] 
    has n, :owned_groups, 'Group', :through => :group_owners 

    has n, :group_members, :child_key => [:member_group_id] 
    has n, :member_groups, 'Group', :through => :group_members 

    #------------------------------------------# 
    # args should be an array of hashes  # 
    # Example: args = [{:id => 1},{:id => 2}] # 
    #------------------------------------------# 
    def self.get_users args 
     users = Array.new 
     args.each do |user| 
     all_users = User.all(user) 
     all_users.each do |u| 
      user_hash = u.attributes 

      user_hash[:owned_groups] = Array.new 
      u.owned_groups.each do |owned_group| 
      g = owned_group.attributes 
      user_hash[:owned_groups].push g 
      end 

      user_hash[:member_groups] = Array.new 
      u.member_groups.each do |member_group| 
      g = member_group.attributes 
      user_hash[:member_groups].push g 
      end 

      users.push user_hash 
     end 
     end 
     return users 
    end 
    end 

    class Group 
    include DataMapper::Resource 

    property :id, Serial, :key => true 
    property :name, String, :required => true, :unique => true 

    has n, :group_owners, :child_key => [:owner_id] 
    has n, :owners, 'User', :through => :group_owners 

    has n, :group_members, :child_key => [:member_id] 
    has n, :members, 'User', :through => :group_members 

    #------------------------------------------# 
    # args should be an array of hashes  # 
    # Example: args = [{:id => 1},{:id => 2}] # 
    #------------------------------------------# 
    def self.get_groups args 
     groups = Array.new 

     args.each do |group| 
     all_groups = Group.all(group) 
     all_groups.each do |g| 
      group_hash = g.attributes 

      group_hash[:owners] = Array.new 
      g.owners.each do |owner| 
      u = owner.attributes 
      group_hash[:owners].push u 
      end 

      group_hash[:members] = Array.new 
      g.members.each do |member| 
      u = member.attributes 
      group_hash[:members].push u 
      end 
      groups.push group_hash 
     end 
     end 
     return groups 
    end 
    end 

    class GroupOwner 
    include DataMapper::Resource 

    property :id, Serial, :key => true 
    belongs_to :owner, 'User' 
    belongs_to :owned_group, 'Group' 
    end 

    class GroupMember 
    include DataMapper::Resource 

    property :id, Serial, :key => true 
    belongs_to :member, 'User' 
    belongs_to :member_group, 'Group' 
    end 
end 

MySQL的: -

mysql> select * from contacts_users; 
+----+-----------+ 
| id | username | 
+----+-----------+ 
| 1 | testuser1 | 
| 2 | testuser2 | 
+----+-----------+ 

mysql> select * from contacts_groups; 
+----+------------+ 
| id | name  | 
+----+------------+ 
| 1 | testgroup1 | 
| 2 | testgroup2 | 
+----+------------+ 
2 rows in set (0.00 sec) 


mysql> select * from contacts_group_owners; 
+----+----------+----------------+ 
| id | owner_id | owned_group_id | 
+----+----------+----------------+ 
| 1 |  1 |    1 | 
| 2 |  2 |    1 | 
| 3 |  1 |    2 | 
| 4 |  2 |    2 | 
+----+----------+----------------+ 
4 rows in set (0.00 sec) 

mysql> select * from contacts_group_members; 
+----+-----------+-----------------+ 
| id | member_id | member_group_id | 
+----+-----------+-----------------+ 
| 1 |   1 |    1 | 
| 2 |   2 |    1 | 
| 3 |   1 |    2 | 
| 4 |   2 |    2 | 
+----+-----------+-----------------+ 
4 rows in set (0.00 sec) 

在調試模式下,這是User.owned_groups產生的MySQL查詢:

SELECT 
     `contacts_groups`.`id`, 
     `contacts_groups`.`name`, 
     `contacts_groups`.`created_at`, 
     `contacts_groups`.`updated_at` 
    FROM `contacts_groups` 
    INNER JOIN `contacts_group_owners` 
     ON `contacts_groups`.`id` = `contacts_group_owners`.`owned_group_id` 
    INNER JOIN `contacts_users` 
     ON `contacts_group_owners`.`owned_group_id` = `contacts_users`.`id` 
    WHERE `contacts_group_owners`.`owned_group_id` = 1 
    GROUP BY 
     `contacts_groups`.`id`, 
     `contacts_groups`.`name`, 
     `contacts_groups`.`created_at`, 
     `contacts_groups`.`updated_at` 
    ORDER BY `contacts_groups`.`id 

版本:

紅寶石 - 2.0.0-P0

西納特拉 - 1.3.4

DataMapper的 - 1.2.0

我失去了一些東西小事?

在此先感謝。

+0

只是爲了快速瀏覽一下,發現你定義的'child_key's但是找不到相應的'parent_key's。這可能不是問題,但我似乎記得這樣做解決了我與DM的一些問題。當我有更多的時間時,我會採取更好的觀點,並添加一個實際的答案,除非你已經知道了...... – 2013-06-06 01:34:44

回答

0

試試這個:

SELECT 
     * 
    FROM 
     `contacts_groups` 
    INNER JOIN `contacts_group_owners` 
     ON `contacts_groups`.`id` = `contacts_group_owners`.`owned_group_id` 
    INNER JOIN `contacts_users` 
     ON `contacts_group_owners`.`owner_id` = `contacts_users`.`id` 
    WHERE 
     `contacts_group_owners`.`owned_group_id` = 1 
+0

我使用的是DataMapper,我不想寫mysql查詢。我想知道模型是否有問題。 順便說一句,輸出應該是testgroup1和testgroup2,但您的查詢只返回testgroup1。 – draxxxeus 2013-05-13 09:45:25

+0

@draxxxeus我不太熟悉python,所以我只想看看我是否可以幫助你查詢,是的,它只返回testgroup1,因爲你有條件''contacts_group_owners'.'owned_group_id' = 1',但它也返回testuser1和testuser2 – Stephan 2013-05-13 10:01:28

+0

那麼,首先它是ruby,其次,我沒有寫MySQL查詢。 DataMapper是一個生成查詢的ORM。無論如何,感謝你的努力。 – draxxxeus 2013-05-13 10:07:14