cypas
cypas

Reputation: 13

Edit multiple entries of has_many, through relation

I am building a membership system for my rails app and have the following models (without validations and everything else):

class User < ActiveRecord::Base
  has_many :memberships
  has_many :subgroups, through: :memberships
end

class Subgroup < ActiveRecord::Base
  has_many :memberships
  has_many :users, through: :memberships
end

The membership model contains a custom attribute, which holds the membership level.

class Membership < ActiveRecord::Base
  belongs_to :subgroup
  belongs_to :user

  scope :guests, -> { where( role: 0 ) }
  scope :users, -> { where( role: 1 ) }
  scope :admins, -> { where( role: 2 ) }
end

I want the user to be able to edit all the memberships for one group in one place. There should be three multiple-select fields per group to choose admins, users & guests. For generating forms I use simple_form.

It should look like this, but filled with the user-names (which should be the easy part) and preselected users for each user-level.

Different built-in solutions like f.association do not work. I tried this for :users (which generates three identical select-fields) and :memberships.

So I am seeking help on building the view & controller.

Upvotes: 0

Views: 79

Answers (1)

Exsemt
Exsemt

Reputation: 1068

You must use scopes in the Subgroup, but not in Membership

class User < ActiveRecord::Base
  has_many :memberships
  has_many :subgroups, through: :memberships

  scope :guests, -> { includes(:memberships).where('memberships.role' => 0) }
  scope :users,  -> { includes(:memberships).where('memberships.role' => 1) }
  scope :admins, -> { includes(:memberships).where('memberships.role' => 2) }
end

or better make new association with lambda wenn you wont to use with simple_form

class Subgroup < ActiveRecord::Base
  has_many :memberships
  has_many :users, through: :memberships

  has_many :only_guests, -> { where('memberships.role' => 0).uniq }, through: :memberships, source: :user
  has_many :only_users,  -> { where('memberships.role' => 1).uniq }, through: :memberships, source: :user
  has_many :only_admins, -> { where('memberships.role' => 2).uniq }, through: :memberships, source: :user

end

view:

<%= f.association :only_users, as: :check_boxes, collection: User.all %>

Upvotes: 1

Related Questions