I have looked at dozens of stack overflow posts and haven't found a solution that works which is why I'm reaching out for an otherwise well documented use case.
I have a button that that should do this.
- When clicked, call a custom controller method that updates the model and does other things
- Call a javascript function to update the page without reloading it (ajax)
Right now, the only way I am able to call a custom controller method is via this way which feels really hacky. I have stripped this down to as simple as possible.
routes.rb
match 'admin/:id/toggleAdmin' => 'admin#toggleAdmin', via: [:patch, :put], as: :toggleAdmin
list.html.erb
<td><%= link_to "Toggle Admin", toggleAdmin_path(id: user.id), method: :patch %></td>
admin_controller.rb
class AdminController < ApplicationController
def toggleAdmin
idToToggle = User.find(params[:id]).id
if idToToggle == current_user.id
redirect_to admin_list_path, danger: "You tried to make yourself a normal user! Don't do that!"
else
User.find(params[:id]).updateToAdmin()
redirect_to admin_list_path, info: "The user with an ID of #{idToToggle} has had their admin attribute toggled!"
end
end
end
What I would like to do instead of reloading the page when an admin is toggled is to just use some javascript to rewrite that part of the dom.
What is a better way to go about this?
Here are just a few of the various resources I have already tried.
- How to call a controller's method from a view?
- Can we call a Controller's method from a view (as we call from helper ideally)?
- Call controller method with rails-Ajax?
- https://www.reddit.com/r/rails/comments/7iyp6g/want_a_button_to_call_a_method_apparently_this_is/
- How do I call a JavaScript function from an html.erb
Thanks for the help.
--- Edit for more information.
Using a clean rails app I now have the ability to call a controller method more cleanly but I am not getting an ajax request to go through that updates the page to show that the action was completed. (I am expecting a boolean value change and a flash). Here is the following relevant code:
users.js
$("#edit-form").html("<%= j render partial: 'form', locals: { user: @user } %>")
_form.html.erb
<%= form_for user do |form| %>
<%= user.admin %>
<% end %>
<%= link_to "Toggle Admin", toggle_admin_user_path(user), method: :put, remote: true %>
edit.html.erb
<h1>Editing User</h1>
<div id="edit-form">
<%= render partial: 'form', locals: { user: @user } %>
</div>
<%= link_to 'Show', @user %> |
<%= link_to 'Back', users_path %>
users_controller.rb Note that I have only included the toggle_admin
and a couple other methods as the rest are just scaffolding.
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy, :toggle_admin]
def toggle_admin
if 1 == 1
logger.info "This is from info"
u = User.find(params[:id])
u.admin = !(u.admin)
u.save
respond_to do |format|
format.js { flash[:info] = "The user with an ID of #{@user.id} has had their admin attribute toggled!" }
end
else
redirect_to admin_list_path, danger: "You tried to make yourself a normal user! Don't do that!"
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_user
@user = User.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def user_params
params.fetch(:user, {})
end
end