0

I'm a bit stuck as with modal window where there are nested form (User Roles below) and which is not working on Update action.

In /controllers/users_controller.rb I have this code:

def update
  @user = User.find(params[:id])
  @role = Role.where(user_id: @user)
  respond_to do |format|
  if @user.update(user_params)
  format.json { head :no_content }
  format.js
  else
  format.json { render json: @user.errors.full_messages,
                         status: :unprocessable_entity }
  end
  end
end

private

  def user_params
  params.require(:user).permit(:name, :email, :password, :password_confirmation, :locale, :psw_change,
  roles_attributes: [:id, :general, :dashboard, :reports, :rights] )
  end

Then there is partial where forms are generated - /views/users/_form.html.erb

<div class="panel-heading">
  <div class="panel-options">
    <ul class="nav nav-tabs">
      <li class="active"><a href="#profile" data-toggle="tab">Profile</a></li>
      <li class=""><a href="#roles" data-toggle="tab">Roles</a></li>
    </ul>
  </div>
</div>
<%= form_for(@user, remote: true, html: { role: "form" }) do |f| %>
<div class="panel-body">
<form method="get" class="form-horizontal">
<!-- Here we render User profile tab -->
<div class="tab-content">
  <div class="tab-pane active" id="profile">
    <div id="error_explanation" class="bg-danger text-danger"></div>
      <div class="form-group">
        <%= f.text_field :name, class: 'form-control', placeholder: "Name"%>
      </div>
      <div class="form-group">
        <%= f.email_field :email, class: 'form-control', placeholder: "E-mail"%>
      </div>
      <div class="form-group">
        <%= f.password_field :password, class: 'form-control', placeholder: "Password"%>
      </div>
      <div class="form-group">
        <%= f.password_field :password_confirmation, class: 'form-control', placeholder: "Password confirmation"%>
      </div>
    </div>
<!-- Here we render User roles tab -->
  <div class="tab-pane" id="roles">
    <%= f.fields_for :roles, @role do |role| %>
      <%= render 'common/roles/general', f: role %>
    <% end %>
    <div class='row'></div>
  </div>
</div>
<div class="form-group">
  <div class="modal-footer">
    <button type="button" class="btn btn-white" data-dismiss="modal">Close</button>
    <%= f.submit  @user.new_record? ? "Create User" : "Update User", class: "btn btn-primary" %>
  </div>
</div>
</form>
</div>
<% end %>

On Update action in console I see this:

Started PATCH "/lv/users/1" for 10.0.2.2 at 2017-03-14 18:13:21 +0000
Processing by UsersController#update as JS
  Parameters: {"utf8"=>"✓", "user"=>{"name"=>"Name 123", "email"=>"some_name@some_mail.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "locale"=>"lv", "psw_change"=>"90", "roles_attributes"=>{"0"=>{"general"=>"seller_buyer", "dashboard"=>"deleter", "reports"=>"deleter", "rights"=>"deleter", "id"=>"1"}}}, "commit"=>"Update User", "locale"=>"lv", "id"=>"1"}
  User Load (2.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  User Load (1.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Role Load (1.8ms)  SELECT "roles".* FROM "roles" WHERE "roles"."user_id" = $1  [["user_id", 1]]
   (0.6ms)  BEGIN
  Role Load (1.2ms)  SELECT "roles".* FROM "roles" WHERE "roles"."user_id" = $1 AND "roles"."id" = 1  [["user_id", 1]]
  User Exists (1.5ms)  SELECT  1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER($1) AND ("users"."id" != $2) LIMIT $3  [["email", "some_name@some_mail.com"], ["id", 1], ["LIMIT", 1]]
   (0.7ms)  COMMIT
  Rendering users/update.js.erb
  Rendered users/_user.html.erb (2.6ms) [cache miss]
  Rendered layouts/_userprofile.html.erb (0.7ms) [cache miss]
  Rendered users/update.js.erb (173.7ms)
Completed 200 OK in 1821ms (Views: 376.4ms | ActiveRecord: 599.1ms)

Strange thing is it does not save User Role updated values, however it would save User Profile updated values if there is such update needed. Obviously I'm missing here something, but I don't see what exactly. I would be happy for any help. Thank you!

The solution

If anyone needs, here is what was wrong in my form. Basically the view part of _form.html.erb was not correct, so values were not updating. It has to be like this:

<!-- Here we render User roles tab -->
  <div class="tab-pane" id="roles">
    <%= f.fields_for :roles, @role do |role| %>
      <%= render 'common/roles/general', f: role %>
    <% end %>
  </div>
</div>
</div>

  <div class="modal-footer">
    <button type="button" class="btn btn-white" data-dismiss="modal">Close</button>
    <%= f.submit  @user.new_record? ? "Create User" : "Update User", class: "btn btn-primary" %>
    <% end %>
  </div>
</form>
matiss
  • 747
  • 15
  • 36
  • Is it because you commented out `@role.update`? – Chris Peters Mar 14 '17 at 18:38
  • @ChrisPeters Sorry, It's not about that - I deleted that line + added user_params – matiss Mar 14 '17 at 18:41
  • Is the roles' relation to users a has_one or a has_many? – Glyoko Mar 14 '17 at 18:45
  • @Glyoko It's `has_many :roles` and `accepts_nested_attributes_for :roles, reject_if: proc { |attributes| attributes[:name].blank? }` in User model – matiss Mar 14 '17 at 18:46
  • Also, it helps others if you indent your code properly. Take a minute to save a minute for everyone who is trying to help you. – Chris Peters Mar 14 '17 at 18:47
  • @ChrisPeters True, I should be more accurate. I forgot I got that line & forgot I should have added `user_params` as that really matters in my case. It seems that there could be something wrong how I'm passing params. So far I tried to do it like in [this answer](http://stackoverflow.com/a/39046713) – matiss Mar 14 '17 at 18:51

0 Answers0