Method is not being called, but is defined in controller and model - ruby-on-rails

I have a method to toggle a user between admin or not-admin. When I click the link I am placed back in the User index with the following in my address bar: http://localhost:3000/users?id=1&method=toggle_admin. As far as I can tell, I have the appropriate code to run the method. Can anyone see a mistake?
Here's the view link_to method:
<%= link_to 'Toggle Admin', { :controller => :users, :method => :toggle_admin, :id => user.id} %>
Here's the routes.rb statement:
match 'users/:id/toggle_admin' => 'users#toggle_admin'
The controller method:
def toggle_admin
#user = User.find(params[:id])
User.toggle_admin(#user)
respond_to do |format|
format.html { redirect_to #users }
end
end
The model method:
def toggle_admin(user)
if user.is_admin.nil or user.is_admin = ''
user.is_admin = false
end
user.toggle is_admin
user.save
end

Trying using :action instead of :method. :method should be used with HTTP verb (i.e GET, PUT and so on)
<%= link_to 'Toggle Admin', { :controller => :users, :action => :toggle_admin, :id => user.id} %>

Related

link_to redirects me to index action and not to the :action one

In my redmine plugin view, I've got this link:
<%= link_to "Add", :controller => "important_user", :action => "u_edit", :u_id => user.id, :p_id => #project.id, :method => :post %>
routes.rb:
resources :important_user do
collection do
post :u_edit
end
end
and controller:
class ImportantUserController < ApplicationController
def u_edit
puts 'edit!'
end
def index
puts 'ciao'
puts params[:p_id]
puts params[:u_id]
end
end
In spite of calling the expected u_edit action, clicking on the link calls the index method (I created in a second moment to avoid the AbstractController::ActionNotFound (The action 'index' could not be found for ImportantUserController) error). I've also tried using this sort of link:
<%= link_to 'Add', { :action => 'create', :u_id => user.id, :p_id => #project.id}, :method => :post %>
But it didn't work either, returning a projects?p_id=1&u_id=1 GET 404. How could I make it call the desired u_edit action?

How can I update attributes with a link in Rails?

I want to update attributes in a data table called "rang" from 0 to 1 using a link.
I have an action:
def ready
#task = Task.find(params[:id])
#task.update_attributes(:ready => '1')
#task.save
redirect_to :action => :index
end
And a link:
<%= link_to 'READY', { :action => :ready, :id => task.id } %>
But nothing happens. What am I doing wrong?
Try :
in routes.rb
resources :tasks do
member do
get 'ready'
end
end
Then link like:
<%= link_to 'READY', ready_task_url(task.id) %>

Form submit says Unkown Action?

Im trying to create a form that submits to a certain action within the current controller (results_controller).
My form code is:
<%= form_tag(:controller => "results", :action => "filter", :id => "filter") do %>
And in the results_controlle.rb i have :
def filter
#setting dispatches
#dispatches = Dispatch.find_by_message_ids(params[:message_ids]) unless params[:message_ids].blank?
unless #dispatches.blank? || #input_messages.blank?
#output_messages = OutputMessage.find_by_dispatch_ids(
#dispatches.collect{|d| d.id }.uniq
)
end
respond_to do |format|
format.html #default rendering
end
end
Yet i get the error:
Unknown action
The action 'filter' could not be found for ResultsController
Any suggestions?
UPDATE
On the same page, i have a form that does work:
<%= form_tag(:controller => "results", :action => "show", :id => "show") do %>
try instead
<% form_tag(filter_result_path(), :method => :get) do %>
and add to your route table
resources :results do
member do
get 'filter'
end
end

Rails Route that Updates or Redirects

Im not sure if I'm doing this right. I have an action that I would like to either copy, create, and save a new object if a user is logged in, or redirect if they are not logged in. Im not using a form here because I am using a stylized button with an image that looks like this:
<a href="/lists/add/<%= #list.id %>" class="button">
<span class="add_list">Learn these words</span>
</a>
and the action looks like this:
def add
if is_logged_in?
list = logged_in_user.copy_list(params[:id])
if list.save
flash[:notice] = "This list is now in your stash."
redirect_to stash_zoom_nav_quiz_path(list, "zoomout", "new", "quizoff")
else
flash[:notice] = "There was a problem adding this list."
redirect_to :back
end
else
redirect_to :controller => "users", :action => "signup_and_login", :list_id => params[:id]
end
end
map.resources :lists, :collection => {:share => :get, :share_callback => :get, :add => :put}
I have added this action as a :put in my routes and I'm not sure if this is right or if the other stuff is the right way to even do it for that matter. Any help is appreciated.
The specific answer to your question is
map.resources :lists, :collection => { :share => :get, :share_callback => :get }, :member => { :add => :put }
add action works on a member, not on a collection.
But there are other problems in your code. First, you should always use Rails helpers to generate the URLs. In fact, the path /lists/add/<%= #list.id %> is wrong. It should be /lists/<%= #list.id %>/add
Change
<a href="/lists/add/<%= #list.id %>" class="button">
<span class="add_list">Learn these words</span>
</a>
to
<% link_to add_list_path(#list), :class => "button" do %>
<span class="add_list">Learn these words</span>
<% end %>
The controller can be simplified. Move the is_logged_in? check in a before filter.
class MyController < ActionController::Base
before_filter :require_logged_user, :only => %w( add )
def add
list = logged_in_user.copy_list(params[:id])
if list.save
flash[:notice] = "This list is now in your stash."
redirect_to stash_zoom_nav_quiz_path(list, "zoomout", "new", "quizoff")
else
flash[:notice] = "There was a problem adding this list."
redirect_to :back
end
end
protected
def require_logged_user
if !is_logged_in?
redirect_to :controller => "users", :action => "signup_and_login", :list_id => params[:id]
end
end
end
Try this in your routes.rb:
map.resources :lists, :member => {:add => :put}, :collection => {:share => :get, :share_callback => :get}
:member - Same as :collection, but for actions that operate on a specific member.

Rendering Actions with Custom Routes

I am trying to maintain a pretty URL when having a user register with failed validation
I have a routes file that looks like the following:
map.resources :users
map.signup '/signup', :controller => "users", :action => "new"
This works well enough, except that if a user enters invalid information during registration then the create method does the following:
def create
#user = User.new(params[:user])
if #user.save
flash[:notice] = "Successfully Registered."
redirect_to root_url
else
render :action => 'new'
end
end
This works, but if the information is correct it switches the URL to domain.com/users. If I switch it to redirect_to '/signup' it works, but all the previous information that was entered is lost, and I would ideally like to maintain that.
Is there any way to keep my nice urls during a failed validation?
You'll need to add conditions to your routes:
# Routes files
map.resources :users
map.signup "/signup", :controller => "users", :action => "new", :conditions => { :method => :get }
map.signup "/signup", :controller => "users", :action => "create", :conditions => { :method => :post }
Then, you'll need to make sure your controller and view handle them correctly:
# Controller
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
flash[:notice] = "Successfully registered."
redirect_to root_url
else
render "new"
end
end
# new.html.erb
<% form_for #user, :url => signup_path do |form| %>
....
<% end %>
Try adding to routes:
map.signup_post '/signup', :controller => "users", :action => "create", :method => :post
And in your form:
<%= form_for #user, :url => signup_post_path do |f| %>

Resources