2008-12-30 41 views
36

Soy nuevo en Ruby on Rails, he completado el Blog Tutorial.Agregar una acción a un controlador existente (Ruby on Rails)

Ahora estoy tratando de agregar una acción adicional al controlador, llamada 'inicio'.

def start 
end 

He añadido una página de vista "app/views/posts/start.html.erb" que contiene nada más que simples html.

Cuando voy a/posts/start obtengo el siguiente error.

ActiveRecord::RecordNotFound in PostsController#show 
Couldn't find Post with ID=start 

entiendo el error, se ejecuta la acción show y empezar no es un documento de identidad válido. ¿Por qué no se ejecuta la acción de inicio? ¿Me falta alguna parte de la arquitectura o configuración de MVC?

A continuación es mi posts_controller.rb

class PostsController < ApplicationController 

    # GET /posts/start 
    def start 
    end 

    # GET /posts 
    # GET /posts.xml 
    def index 
    @posts = Post.find(:all) 
    respond_to do |format| 
     format.html # index.html.erb 
     format.xml { render :xml => @posts } 
    end 
    end 

    # GET /posts/1 
    # GET /posts/1.xml 
    def show 
    @post = Post.find(params[:id]) 
    respond_to do |format| 
     format.html # show.html.erb 
     format.xml { render :xml => @post } 
    end 
    end 

end 

Sí he reiniciado el servidor y probado con Mestizo y WEBrick.

+0

Por favor, vuelva a seleccionar ... "on" no debería ser una etiqueta – andHapp

Respuesta

26

Su ruta no está configurada para permitir esa ruta. Suponiendo que está usando el andamiaje defecto, poner esta línea antes de la línea map.resources :posts en config/routes.rb:

map.connect "posts/:action", :controller => 'posts', :action => /[a-z]+/i 

La expresión regular para :action restringe a solo az (para evitar la captura de las cosas como/mensajes/1). Se puede mejorar si necesita subrayados o números en sus nuevas acciones.

45

El error que está cometiendo es realmente bastante común.

Básicamente, Rails asigna automáticamente las URL de sus andamios. Por eso, cuando creaste los andamios de Publicaciones, Rails está mapeando las rutas URL para ello. Una de esas rutas es la URL para ver una sola publicación:/posts/(post_id)

Por lo tanto, cuando ingresa la URL/posts/start Rails cree que está diciendo "Oye, dame la publicación con ID = start. Así que Rails se queja de que el método show no puede encontrar una publicación con dicha ID.

Una forma rápida de solucionar esto es asegurarse de que su config/routes.rb tenga la ruta para la acción de inicio antes del andamio rutas:

# Route for start action 
map.connect '/posts/start', :controller => 'posts', :action => 'start' 
# Default mapping of routes for the scaffold 
map.resources :posts 

De todos modos, espero que ayude

+1

Gracias por la explicación, tendré que leer más sobre las rutas. – Mark

+4

Creo que una de las cosas que más ayuda cuando se trata de entender cómo funcionan las rutas en RoR es recordar que se evalúan de arriba abajo. Por lo tanto, generalmente es una mejor práctica tener sus rutas más específicas antes de las rutas generales (catch-all). – David

+0

Utilicé el comando '/ pages/action',: controller => 'pages',: action => 'action' y funcionó. –

0

I Foun. d la solución a mi problema, en el archivo routes.rb donde

map.resource :post 

añadí con el argumento de recogida, por lo que quedó de esta manera:

map.resource :post, :collection => { :my_action => :get} 
+2

En Rails 3, esto agrega '" collection "=> {" my_action "=>: get}' a los parámetros GET. – rxgx

1

Esto funciona:

map.resource :post, :collection => { :my_action => :get} 
+0

En Rails 3, la opción de recopilación agrega '" collection "=> {" my_action "=>: get}' a los parámetros GET. – rxgx

8

Intente esto si está utilizando los carriles 3.0.3

en su ruta.rb

resource :posts do 
    collection do 
    get 'start' 
    end 
end 

esto podría ayudar

2

Quiero decir, a veces Carriles vuelve pegajoso con las rutas de almacenamiento en caché, incluso en el entorno dedesarrollo.

Puede ayudar a reiniciar su servidor Rails. Esto me ha funcionado más veces de las que puedo contar al recibir este error.

33

En Los Carriles uso 4.x:

get '/posts/start', :controller => 'posts', :action => 'start' 

En Los Carriles uso 3.x:

match '/posts/start', :controller => 'posts', :action => 'start' 

en lugar de

map.connect '/posts/start', :controller => 'posts', :action => 'start' 

se resolvió mi problema.

Cuestiones relacionadas