0

After a number of hours reading stackoverflow and watching railscasts, I've decided to post. The question is very similar if not identical to many other questions here but I'm just not getting it. This is my first has_many_through association.

class User < ActiveRecord::Base
...
has_many :affiliations
has_many :sublocations, through: :affiliations
...
end

class Sublocation < ActiveRecord::Base
...
has_many :affiliations
has_many :users, through: :affiliations
...
end

class Affiliations < ActiveRecord::Base
...
belongs_to :user
belongs_to :sublocation
...
end

The affiliations table has the usual user_id and sublocation_id columns. It also has boolean column named 'default'. In my 'new/edit user' form(s), I'm needing to select one or more sublocations via checkboxes and also include a way to mark a sublocation as 'default'.

Again, I've read example after example but something just isn't 'clicking' in my brain. I'm not necessarily looking for an exact solution but a nudge in the right direction.

Many thanks, CRS

Clay
  • 162
  • 2
  • 9
  • I don't think you should have a boolean field 'default' in Affiliations table. You want to make a sublocation default, and not the affiliation. – 18bytes Nov 07 '12 at 07:24
  • Not sure whether its right, you need to have one :sub_location as default in a user. So check whether you can add "has_one :sub_location" to the User (which will be the default). – 18bytes Nov 07 '12 at 07:26
  • The default would have to be in the affiliations table as every user could have a different default sublocation. Also, didn't know if I could use a has one and has many on the same model for another model. – Clay Nov 07 '12 at 07:35

1 Answers1

0

My suggestion:

Create a user form to set up the associations between User and Sublocation

I am assuming the sublocations have been pre-populated?

users_controller.rb

def new
    @user = User.new
    @sublocations = Sublocation.all
    respond_to do |format|
      # what ever
    end
end

def create
    @user = User.new(params[:user])
    params[:sublocation_ids].each do |key, value|
      @user.affiliations.build(sublocation_id: value)
    end
    respond_to do |format|
      if @user.save
        # what ever
      else
        # what ever
      end
    end
 end

def show
    @user = User.find(params[:id])
    @affiliations = @user.affiliations
end

def set_default
    affiliation = Affiliation.find(params[:affiliation_id])
    Affiliation.where(user_id: params[:user_id]).update_all(default: false)
    affiliation.toggle!(:default)
    redirect_to affiliation.user, notice: "Default sublocation set"
 end

users/_form.html.haml

= form_for @user do |f|

  .field
    # fields for user attributes

  .field

    %h1 Sublocations

    = f.fields_for "sublocations[]" do
      - for sublocation in @sublocations
        = label_tag sublocation.name
        = check_box_tag "sublocation_ids[#{sublocation.name}]", sublocation.id, @user.sublocations.include?(sublocation)
  .actions
    = f.submit 'Save'

Then perhaps on the user show page, list all their sublocations and create a form for them to set a default.

users/show.html.haml

= form_tag user_set_default_path(@user), method: :put do
  %table
    %tr
      %th Sublocation
      %th Default?
    - @affiliations.each do |affiliation|
      %tr
        %td= affiliation.sublocation.name
        %td= radio_button_tag :affiliation_id, affiliation.id, affiliation.default? ? {checked: true} : nil

  = submit_tag "Set default"

routes.rb

resources :users do
  member do
   put "set_default"
  end
end 

Hope this helps or at least gets you on the right path.

veritas1
  • 8,740
  • 6
  • 27
  • 37
  • This has got me well on my way. I'm wanting to set the default in the new user form since users shouldn't be able to set their own default sub location, but in the meantime, I'll redirect to the 'set default' form after the user is created. Many thanks. – Clay Nov 07 '12 at 15:32