Reputation: 49
I have a link_to
in a view that I would like to use to call a method in my controller to update the model.
Here's the view code:
<tbody>
<% @users.each do |user| %>
<tr data-user-id="<%= user.id %>">
<td><%= user.email %></td>
<td><%= link_to 'Show', user %></td>
<td><%= link_to 'Edit', edit_user_path(user) %></td>
<td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td>
<td><%= link_to 'Admin', user, method: :admin %></td>
</tr>
<% end %>
</tbody>
this link is the specific one that isnt working, since it's not a default method in the users controller
<td><%= link_to 'Admin', user, method: :admin %></td>
The admin method in my controller looks like this
def admin
@user = User.find(params[:id])
if @user.isadmin?
redirect_to '/users', alert: 'User was updated to admin.'
else
redirect_to '/users', alert: 'User is already an admin.'
end
end
I dont have any route defined in the routes.rb file because I'm not sure how to define it correctly. Is there an issue with the view or is an issue with not having a route. I thought that i could specify the controller and action in the link but that doesnt seem to be working.
Here's the console output
Started POST "/users/5" for 192.168.1.1 at 2019-03-13 22:25:50 -0400
ActionController::RoutingError (No route matches [POST] "/users/5"):
actionpack (5.2.2) lib/action_dispatch/middleware/debug_exceptions.rb:65:in `call'
web-console (3.7.0) lib/web_console/middleware.rb:135:in `call_app'
web-console (3.7.0) lib/web_console/middleware.rb:22:in `block in call'
web-console (3.7.0) lib/web_console/middleware.rb:20:in `catch'
web-console (3.7.0) lib/web_console/middleware.rb:20:in `call'
actionpack (5.2.2) lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
railties (5.2.2) lib/rails/rack/logger.rb:38:in `call_app'
railties (5.2.2) lib/rails/rack/logger.rb:26:in `block in call'
activesupport (5.2.2) lib/active_support/tagged_logging.rb:71:in `block in tagged'
activesupport (5.2.2) lib/active_support/tagged_logging.rb:28:in `tagged'
activesupport (5.2.2) lib/active_support/tagged_logging.rb:71:in `tagged'
railties (5.2.2) lib/rails/rack/logger.rb:26:in `call'
sprockets-rails (3.2.1) lib/sprockets/rails/quiet_assets.rb:13:in `call'
actionpack (5.2.2) lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
actionpack (5.2.2) lib/action_dispatch/middleware/request_id.rb:27:in `call'
rack (2.0.6) lib/rack/method_override.rb:22:in `call'
rack (2.0.6) lib/rack/runtime.rb:22:in `call'
activesupport (5.2.2) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'
actionpack (5.2.2) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (5.2.2) lib/action_dispatch/middleware/static.rb:127:in `call'
rack (2.0.6) lib/rack/sendfile.rb:111:in `call'
railties (5.2.2) lib/rails/engine.rb:524:in `call'
puma (3.12.0) lib/puma/configuration.rb:225:in `call'
puma (3.12.0) lib/puma/server.rb:658:in `handle_request'
puma (3.12.0) lib/puma/server.rb:472:in `process_client'
puma (3.12.0) lib/puma/server.rb:332:in `block in run'
puma (3.12.0) lib/puma/thread_pool.rb:133:in `block in spawn_thread'
routes.rb
resources :users
post 'users/:id' => 'users#admin'
Upvotes: 0
Views: 492
Reputation: 638
In view file your Admin link is incorrect. Method should be :delete, :post etc not :admin
<td><%= link_to 'Admin', user, method: :admin %></td>
Here's the fix -
Solution #1
# In view
<td><%= link_to 'Admin', admin_user_path(user) %></td>
Route should be
resources :users do
member do
get 'admin'
end
end
Solution #2
# In view
<td><%= link_to 'Admin', admin_user_path(user), method: :post %></td>
Route should be
resources :users do
member do
post 'admin'
end
end
Upvotes: 0
Reputation: 26071
this should create the route you need.
post 'users/:id/admin' => 'users#admin'
your link would look like
<% = link_to 'Admin', users_admin_path(user) %> # or whatever rails names your route
Upvotes: 1
Reputation: 1758
Try changing your link to:
<%= link_to "Admin", admin_path(user) %>
And your route to:
post 'admin', to: 'admin#users', as: :admin
Upvotes: 0