2016-04-17 89 views
0

我在用户和工作区之间有一个HABTM关联,它们也有组。问题是我无法从用户插入数据介绍组。通过HABTM插入数据

class User < ActiveRecord::Base 
has_and_belongs_to_many :workspaces #, dependent: :destroy 
has_many :groups,      through: :workspaces 
end 

class Workspace < ActiveRecord::Base 
    has_and_belongs_to_many :users,   dependent: :destroy 
    has_many     :groups,   dependent: :destroy 
end 

这是连接表迁移:

class CreateUsersAndWorkspaces < ActiveRecord::Migration 
    def change 
    create_table :users_workspaces, id: false do |t| 
     t.belongs_to :user, index: true 
     t.belongs_to :workspace, index: true 
    end 
    end 
end 

在轨控制台,当我尝试创建新组:

u.groups.create!(name: "txt", workspace_id: 1)                      
(0.1ms) begin transaction 
(0.2ms) rollback transaction 
    ActiveRecord::HasManyThroughNestedAssociationsAreReadonly: 
    Cannot modify association 'User#groups' because it goes 
    through more than one other association. 

有没有办法从用户创建群组?

编辑: 在@evedovelli的帮助下,我可以让它工作。但由于user.workspace是一个ActiveRecord_Associations_CollectionProxy,它不是一个工作区类,而是一个集合。追加“第一”,解决了这个问题,所以最后的代码是:

u.workspaces(id: 1).first.groups.create!(name: "txt") 

现在假设我有更多的关联:

u.workspaces(id: 1).first.groups(id: 2).first.modelN(id:3).first.modelNplus1.create!(name: "txt") 

我的最后一个问题是,这是正确的方法是什么?

+0

问题是Rails的无法找出什么工作区中的组从用户应加(即使你像创建时那样在创建时指定worspace_id)。 由于您在创建组时已经知道了工作空间ID,您不能简单地使用'u.workspaces(id:1).groups.create!(name:“txt”)''创建吗? 这样可以为正确的用户工作区创建组。 (我会输入这个答案) – evedovelli

+0

刚刚更新了答案。使用'find_by_id'通过模型中的正确标识进行搜索。 'first'将总是返回列表中的第一个项目,这不是你想要的。 – evedovelli

回答

1

的问题是,Rails可以找不出什么用户工作区应加入(即使你为你做了指定在创建时worspace_id)。

正如错误消息中所述,HasManyThrough的嵌套关联是只读的。因此,您可以直接从用户中读取,但无法创建它们。

既然你创建组时,已知workspace_id,你可以简单地创建组:

u.workspaces.find_by_id(1).groups.create!(name: "txt") 

这样,它会创建为右用户工作区

,你应该能够保持通过其他协会这样与去:

u.workspaces.find_by_id(1).groups.find_by_id(2).modelN.find_by_id(3).modelNplus1.create!(name: "txt") 
+0

我能够 worksp.groups.create!(name:“txt”) 但不是 u.workspaces(id:1).groups.create!(名称:“txt”) NoMethodError:未定义的方法'组'为# Gaston

+0

感谢您的回答。我更新了我的问题:D – Gaston