Tom Bartel
Tom Bartel

Reputation: 56

Rails 3 has_many :through concept

I need some conceptual help:
Assume your Users are essentially a business. You have Employees and you have Staff Positions. Essentially, one employee could hold multiple positions and one position could hold multiple employees.
My have_many :through is working between the Employees and the Positions through a join table Staffization. However, my edit form for the employee is returning ALL the Positions as checkboxes for the whole app, not just the ones for this particular User. And, none are being saved when I submit an update. Do I need to do something different with my associations, or is there a better way to narrow the data in the forms?
My models:

class User < ActiveRecord::Base
  has_many    :employees,  :dependent => :destroy
  has_many    :positions,  :dependent => :destroy

class Employee < ActiveRecord::Base
  belongs_to :user
  has_many :positions, :through => :staffizations
  has_many :staffizations, :dependent => :destroy

class Position < ActiveRecord::Base
  belongs_to :user
  has_many :employees, :through => :staffizations
  has_many :staffizations, :dependent => :destroy

class Staffization < ActiveRecord::Base
  belongs_to :employee
  belongs_to :position

My employee edit fields form is set up to return checkboxes for the possible positions the employee could hold but is return all the positions in the whole app and is not updating the data when I hit submit:

 - Position.all.each do |position|
   = check_box_tag :position_ids, position.position_name, @employee.positions.include?(position), :name => 'employee[position_ids][]'
   = label_tag :position_ids, position.position_name

My employees controller update def added the line for the have_many :through association. Is this where I should narrow the return down to the current signed in user's employees and positions?

@employee.attributes = {'position_ids' => []}.merge(params[:employee] || {})

Upvotes: 0

Views: 1193

Answers (3)

m_x
m_x

Reputation: 12564

First, shouldn't you be using :

class Employee
  has_and_belongs_to_many :positions
end

class Position
  has_and_belongs_to_many :employees
end

then, you could narrow the available positions with :

Position.where(:user_id => @employee.user_id).each # etc.

you could even make a scope for it:

class Position
  def available_for_employee employee
    where(:user_id => employee.user_id)
  end
end

... and then use this in a helper that generates your checkboxes

def position_checkboxes_for_employee employee
  Position.available_for_employee(employee).each do |position|
    = check_box_tag :position_ids, position.position_name, @employee.positions.include?(position), :name => 'employee[position_ids][]'
    = label_tag :position_ids, position.position_name
  end
end

Upvotes: 2

Tom Bartel
Tom Bartel

Reputation: 56

Thanks to a friend, since my have_many through between my employees and positions belongs to the business. I needed to add the attr_accessible position_ids and attr_accessible employee_ids to the respective models. In addition, in my employee view field, I needed to add the options so that my call for positions only calls those positions associated with this business, like so:

  - Position.find_all_by_user_id(@employee.user_id).each do |position|
   = check_box_tag :position_ids, position.id, @employee.positions.include?(position), :name => 'employee[position_ids][]'
   = label_tag :position_ids, position.position_title

Upvotes: 0

user783774
user783774

Reputation:

returning ALL the positions as checkboxes is exactly what you'd want, no? what if a employee changes positions? you'd need that checkbox then, not only the checked ones..

Upvotes: 1

Related Questions