SRack
SRack

Reputation: 12203

Rails creating a form to update a has-many-through instance variable

I'm looking to create a form that updates a User's has_many through relationship. To be more specific, each User has many Weekdays (the model is working perfectly) and I'd like to add a form to add extra weekdays, selectable from check boxes. For reference, the (abridged) model is:

class User < ActiveRecord::Base
  has_many :user_weekdays, dependent: :destroy
  has_many :weekdays, -> { uniq }, through: :user_weekdays
end

class Weekday < ActiveRecord::Base
  has_many :user_weekdays
  has_many :users, -> { uniq }, through: :user_weekdays
end

i.e. a 'User.find(1).weekdays' might currently return Sunday and Monday, though I'd like to have a form that provides a list of all the weekdays, with those selected pushed to the user.weekdays when it's submitted.

I'm presuming it should work something like User.find(params[:id]).weekdays << (the form entries) but don't know how to do this.

I'm pretty new to Rails, and am a little lost when it comes to any form out of the ordinary. How do I build this? I've had a hunt on SO but can't find anything definitive to apply. Any advice on how to implement this in the view and controller would be GREATLY appreciated. Thanks in advance, Steve.

Upvotes: 0

Views: 131

Answers (2)

SRack
SRack

Reputation: 12203

Got this working, using Ryan Bates' excellent Railscast on the subject. Code as follows:

  <%= hidden_field_tag "user[weekday_ids][]", nil %>
  <%= Weekday.all.each do |weekday| %>
    <%= check_box_tag "user[weekday_ids][]", weekday.id, @user.weekday_ids.include?(weekday.id), id: dom_id(weekday) %>
    <%= label_tag dom_id(weekday), weekday.day %><br>
  <% end %>

Not dissimilar to the above, though this is running perfectly for me. It wouldn't save to begin with, as I hadn't defined the extra parameters with Devise (that is managing my User model). The code to fix this was as follows:

def configure_permitted_parameters
  devise_parameter_sanitizer.for(:account_update) do |u|
    u.permit({ weekday_ids: [] }, { wo_type_ids: [] }, :email, :current_password,
            :password_confirmation, :password) 
  end
end

Hope this proves useful for someone - and checkout the video tutorial, it's the perfect concise run through (and well worth subscribing for)!

Steve.

Upvotes: 1

MayankJ
MayankJ

Reputation: 446

If you want to display checkbox for each weekday, then you can try this code:

<% Weekday.all.each do |weekday| %>
<%= check_box_tag "user[weekday_ids][]", weekday.id, current_user.weekday_ids.include?(weekday.id) %>
<% end %>

This "weekday_ids" contain your weekday ids that you selected, and will associate with your user model through user_weekdays when it will save.

Upvotes: 0

Related Questions