0

I have a HABTM association between Users and Workspaces, which also has groups. The problem is I can't insert data intro groups from users.

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

This is the join table migration:

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

In rails console, when I try to create new group:

 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.

Is there a way to create groups from the user?

EDIT: With help from @evedovelli I could make it work. but since user.workspace was a ActiveRecord_Associations_CollectionProxy, it was not a workspace class, but a collection. appending 'first', solved the problem, so the final code is:

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

Now suppose I have more associations:

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

my final question is, is this the correct way?

Gaston
  • 1,004
  • 1
  • 9
  • 23
  • The problem is that Rails cannot find out to what workspace the group from user should be added to (even if you to specify the worspace_id on creation as you did). Since you known the workspace id when creating the group, can't you simply create with `u.workspaces(id: 1).groups.create!(name: "txt")`? This way it may create the group for the right user's workspace. (I'll will enter this as an answer) – evedovelli Apr 17 '16 at 00:49
  • Just updated the answer. Use `find_by_id` to search by the correct id in the model. `first` will always returns the first item from the list, and that's not what you want. – evedovelli Apr 19 '16 at 02:01

1 Answers1

1

The problem is that Rails cannot find out to what user's workspace the group should be added to (even if you to specify the worspace_id on creation as you did).

As mentioned in the error message, the nested associations for HasManyThrough are read only. So you can read groups directly from an user, but you can't create them.

Since you known the workspace_id when creating the group, you can simply create the group with:

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

This way it will create the group for the right user's workspace.

And you should be able to keep going with that through other associations like this:

u.workspaces.find_by_id(1).groups.find_by_id(2).modelN.find_by_id(3).modelNplus1.create!(name: "txt")
evedovelli
  • 2,115
  • 28
  • 28
  • I am able to worksp.groups.create!(name: "txt") but not u.workspaces(id: 1).groups.create!(name: "txt") NoMethodError: undefined method `groups' for # – Gaston Apr 18 '16 at 12:19