Rails 3: Problem with a route to new action - ruby-on-rails-3

I have a problem with rails 3 routes.
I want add a new action called "gestion_etudiant" with a new view "gestion_etudiant.html.erb".
I have on my index page a link like this
<%= link_to "Administration", {:controller => "users", :action => "gestion_etudiant"} %>
I also try this:
<%= link_to "Administration", "/users/gestion_etudiant" %>
In my controller:
def gestion_etudiant
#users = User.find(:all)
end
but when I clic on the link, I always have this error:
ActiveRecord::RecordNotFound in UsersController#show
Couldn't find User with ID=gestion_etudiant
I have this in my routes file:
resources :users
And I've also try to add:
match "users/gestion_etudiant", :to => "users#gestion_etudiant"
and
resources :users, :only => [:gestion_etudiant]
But I can not access my page "gestion_etudiant.html.erb". Can anybody suggest why?

Try this:
# router:
resources :users do
get :gestion_etudiant, :on => :collection
end
# view:
link_to "Administration", gestion_etudiant_users_path
# Controller
def gestion_etudiant
#users = User.all # Don't use find with :all as it will be deprecated in rails 3.1
end

In your routes, try:
resources :users do
collection do
get 'gestion_etudiant'
end
end
You can check the routes you have in your application by running rake routes

Related

Links to resources with friendly URLs

I'm trying to write a blog in Rails 3, so I have posts. I want to make nice routes for the posts like this: posts/year/month/day/post-title. So I overrided to_param in model/post.rb and use friendly_id for title:
extend FriendlyId
friendly_id :title, :use => :slugged
def to_param
"#{year}/#{month}/#{day}/#{title.parameterize}"
end
And I added this to routes.rb:
resources :posts do
collection do
match ":year/:month/:day/:id", :action => "show"
end
member do
post 'comment'
delete 'comment/:comment_id', :action => 'destroy_comment', :as => 'destroy_comment'
end
end
In show this works:
<%= link_to image_tag("/images/edit_icon.png"),
{ :controller => 'posts', :action => 'edit' }, :id => #post %>
But in index it says
routing error:
No route matches {:action=>"edit", :controller=>"posts"}.
I'm new to Rails and I haven't managed to find out what causes this error. Can anyone help me figure out what I do wrong?

Rails 3 Correctly routing the destroy action for a session

I am refactoring my access_controller into a sessions_controller and can't seem to get my destroy action working properly.
Logging in seems to work fine, but I am unable to log out of a session. Here is the link I have for logging out:
<%= link_to("Logout", :controller => "sessions", :action => 'destroy') %>
routes.rb
resources :sessions
sessions_controller.rb
class SessionsController < ApplicationController
def new
end
def create
...
end
def destroy
session[:user_id] = nil
flash[:notice] = "You are now logged out"
redirect_to root_url
end
end
When I click "Logout" I get redirected to "/sessions/destroy" with a message of "The action 'show' could not be found for SessionsController". The destroy actions seems to want an id, but I don't need to pass in an id, I just want to run the action.
Ah, I found the answer here: http://railscasts.com/episodes/250-authentication-from-scratch
I need to set up my routes as follows:
get "log_out" => "sessions#destroy", :as => "log_out"
get "log_in" => "sessions#new", :as => "log_in"
resources :sessions

Nested model form not working properly - need to pinpoint POST/GET redirect

I have a nested model form that isn't functioning properly. The POST is to the proper place, but then the GET reroutes me. So I'm wondering if anyone can help explain what I'm doing wrong.
I have two models: User and Profile. Code for them below:
User:
class User < ActiveRecord::Base
attr_accessor :password, :email
has_one :profile, :dependent => :destroy
accepts_nested_attributes_for :profile
...
end
Profile:
class Profile < ActiveRecord::Base
attr_accessible :first_name, :last_name, etc.
belongs_to :user
accepts_nested_attributes_for :user
...
end
New/Create from both models:
class UsersController < ApplicationController
def new
#user = User.new
if logged_in?
redirect_to current_user.profile
end
end
def create
#user = User.new(params[:user])
if #user.save
redirect_to signup_path, :notice => 'User successfully added.'
else
render :action => 'new'
end
end
class ProfilesController < ApplicationController
def new
#profile = Profile.new
end
def create
#profile = Profile.new(params[:profile])
if #profile.save
redirect_to profile_path, :notice => 'User successfully added.'
else
render :action => 'new'
end
end
def index
#profile = current_user.profile
end
My signup (two step process) mixes the models, so as I said I'm using a nested model form in my Users new.html.erb file. Code form_for and f.fields_for below:
<%= form_for(:user, :url => signup_path, :html => {:id => 'homepage'}) do |f| %>
<%= f.fields_for :profile do |f| %>
Now when I enter data into the form, my routes.rb file seems to POST to the proper place (/signup so profile can be filled out further), but GET routes me to /login.
Routes.rb:
match '/login' => "sessions#new", :as => "login"
match '/signup' => 'profiles#new', :as => "signup"
match 'skip/signup', :to => 'info#signupskip'
match 'skip/profiles/new', :to => 'profiles#newskip'
root :to => 'users#new'
resources :users
resources :profiles
In rails server:
Started POST "/signup" for 127.0.0.1 at Sun Aug 28 19:54:11 -0400 2011
Processing by ProfilesController#new as HTML
Started GET "/login" for 127.0.0.1 at Sun Aug 28 19:54:11 -0400 2011
Processing by SessionsController#new as HTML
Rendered sessions/new.html.erb within layouts/application (32.1ms)
I'm wondering if the problem is in my layouts/application file, specifically this code:
<% if logged_in? %>
<%= render 'layouts/header_in' %>
<% else %>
<%= render 'layouts/header_out' %>
<% end %>
Can anyone help explain to me what I'm doing wrong?
UPDATE:
I deleted the if/else argument in `layouts/application' and it was still redirected. So I'm back to wondering what's going on.
I believe your problem has to do with an inherent issue (though arguably not problem) with HTTP protocol. You cannot return a redirect to a POST request. Alternatives include calling the other method from within the first controller action, or rendering the correct page directly from that action, or some mix of both.

Rails 3 link_to rake task

I've created a rake task in my application and now I want the task to be accesible for app users from a link on a menu, but I don't know how to invoke it from there. Something like this...?
<%= link_to t('backup'), Rake::Task['backup'].invoke %>
I tried as you said, but the next error appears:
NameError (uninitialized constant MyTasksController::Rake)
Edit answer:
I finally could do it by this way:
class MyTasksController < ApplicationController
def rake_it
system ('rake backup:db:mysql')
redirect_to :action => 'index', :controller => '/events'
end
end
You can't do it. Link_to can link to something static or controller action. So you need to create some action, where you can invoke your Rake Task.
class MyTasksController < ApplicationController
def rake_it
Rake::Task['backup'].invoke
end
end
<%= link_to t("backup"), {:controller => :my_tasks, :action => "rake_it"} %>

Rails Routing Error

Rails is giving me a route error even though the route appears to
be in the route list.
The form is doing a Post to try to hit the update route on the Admin::ProductsController.
The edit route, index route, and show route work fine.
Using Rails 3.0.5 and ruby 1.9.2
Anyone have an idea? I can't seem to see the problem.
Error
No route matches "/admin/products/2039"
Code from ERB File that is generating the form
<%= form_for :product, #product, :url => { :action => "update" } do |f| %>
Products Controller method at this point is just a stub of
def update
puts params.inspect
end
Routes File
Analytics::Application.routes.draw do
match 'login' => 'Authentication#login', :via => [:get, :post]
namespace :admin do
# Directs /admin/products/* to Admin::ProductsController
# (app/controllers/admin/products_controller.rb)
root :to => 'AdminInterface#index', :via => :get
resources :products
resources :publishers, :only => [:edit, :update]
match 'publishers/query/:subset' => 'Publishers#index', :as => :publishers_subset, :via => [:get, :post]
end
end
According to your routes, shouldn't that be
= form_for [:admin, #product] do |f|
Your form_for can just be:
<%= form_for #product do |f| %>
If #product is an existing object then it will automatically know to go the update action of the ProductsController.