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>