Search code examples
ruby-on-railsrubyformbuilderfields-for

Rails fields_for pulling model name instead of ID for params id


I'm using fields_for to create a page for editing multiple user objects in my app. I've been using this Railscast video as a point of reference. http://railscasts.com/episodes/198-edit-multiple-individually The issue I am running into is that rather than using the user id when generating the html, the form builder is inserting the user's name. I have no idea why. Below is my controller, view, and some of the html generated.

View

 Manage Your User Licenses
User License Management for <%= @org.title %>
<%= form_tag update_many_user_licenses_path, :method => :put do %>
  <% for user in @users %>
    <%= fields_for "users[]", user do |user_fields| %>
      <div><%= user.name %></div>
      <div><%= user_fields.label :active_license %>
      <%= user_fields.check_box :active_license %></div>
    <% end %>
  <% end %>
  <%= submit_tag "Mark as Complete" %>
<% end %>

Controller

class UserLicensesController < ApplicationController
  before_filter :authenticate_user!

  def manage
    @org = current_user.organization
    @users = @org.users
  end
  def update_many
    @users = User.find(params[:users])
    @users.each do |user|
      user.update_attributes!(params[:user].reject { |k,v| v.blank? })
    end
    flash[:notice] = "Updated users licenses."
    redirect_to manage_user_licenses_path
  end
end   

HTML

<div>Tyrel Denison</div>
<div><label for="users_Tyrel-Denison_active_license">Active license</label>
<input name="users[Tyrel-Denison][active_license]" type="hidden" value="0" /><input   id="users_Tyrel-Denison_active_license" name="users[Tyrel-Denison][active_license]" type="checkbox" value="1" /></div>

Solution

  • While I'm not familiar with the LinkedIn API Gem, based on our discussion, it seems the to_param method is being overwritten in your User model.

    From the comments, this is apparently what your to_param method looks like:

    def to_param  # TODO USe something better than this plz  
        self.name.gsub(/\s+/, '-')  
    end
    

    You reported that rather than using the user id when generating the html, the form builder is inserting the user's name, and as you can see, this is precisely what is happening in that method. Ultimately, fields_for calls to_param, and you don't have a choice in that matter.

    I would be quite astonished that the LinkedIn gem required you to override that method, as it would most definitely break any model that used it, as you experienced (and I can't explain why the other developer decided to do that - it's possible they innocently wrote the method without realizing it already exists in the base class)

    I can't give you more detailed information without examining the system more closely, however I would suggestion trying to find how/where to_param is being used (assuming it is being called explicitly somewhere), and create a separate method instead.