Páginas estáticas en Ruby on Rails

76

¿Cuál es la forma estándar de hacer una aplicación Ruby on Rails que tendrá páginas como

  • Casa
  • Acerca de
  • Contacto

Apreciaría si alguien tuviera enlaces o respuestas en lugar de simplemente decir usar una gema porque quiero aprender a hacer aplicaciones web simples con ese comportamiento.

LuckyLuke
fuente

Respuestas:

113

Depende de cómo quiera manejar el contenido de esas páginas.

Enfoque n. ° 1: almacenar contenido en vistas

Si solo desea colocar todo su contenido en vistas ERB, entonces un enfoque muy simple es crear un PagesControllercuyo propósito sea tratar con páginas estáticas. Cada página está representada por una acción en el controlador.

pages_controller.rb:

class PagesController < ApplicationController
  def home
  end

  def about
  end

  def contact
  end
end

rutas.rb:

match '/home' => 'pages#home'
match '/about' => 'pages#about'
match '/contact' => 'pages#contact'

Luego, cree las vistas home.html.erb, about.html.erb y contact.html.erb en app / views / pages. Estas vistas contienen cualquier contenido que desee en sus páginas estáticas. De forma predeterminada, usarán el diseño application.html.erb de su aplicación.

También querrá examinar el almacenamiento en caché de la página para aumentar el rendimiento.


Enfoque n. ° 2: almacenar contenido en la base de datos

Otro enfoque que he usado es hacer un CMS muy básico para páginas estáticas. En este caso, las páginas están representadas en el modelo. Utiliza la gema friendly_id para manejar los slugs de cada página para que puedan ser recuperados por un bonito nombre en la URL (por ejemplo, / about) en lugar de por ID.

page.rb:

class Page < ActiveRecord::Base
  attr_accessible :title, :content

  validates_presence_of :title, :content

  has_friendly_id :title, :use_slug => true, :approximate_ascii => true
end

pages_controller.rb:

class PagesController < ApplicationController
  def show
    @page = Page.find(params[:id])
    render 'shared/404', :status => 404 if @page.nil?
  end
end

show.html.erb:

<%= raw @page.content %>

rutas.rb:

match '/:id' => 'pages#show'

Nota: ponga esta entrada al final de routes.rb ya que coincide con todo.

Entonces, la forma en que desea crear, editar y actualizar las páginas depende de usted: puede tener una interfaz de administración o integrarla en su interfaz pública de alguna manera. Este enfoque también puede beneficiarse del almacenamiento en caché de páginas.

Jeff
fuente
8
Ni siquiera necesita incluir los métodos vacíos en el controlador. EDITAR: Además, puede poner esto como una especie de ruta 'atrapar todo' después de todo lo demás: coincidir ': acción' => 'páginas' para evitar la necesidad de actualizar las rutas cuando agrega una nueva página. Sin embargo, es posible que desee tener cuidado con eso si tiene muchas rutas complicadas.
Graham Edgecombe
Muchas gracias Jeff, ¡fue perfecto! La idea que tenía en mente era el enfoque 2. pero no sabía cómo hacer URL bonitas como esa. ¡Una vez más, gracias!
LuckyLuke
Puede hacer algo como domain.com/p/blog-post-slug para el partido y luego hacer coincidir eso con /p/:id. P es para 'post' y realmente puede ser cualquier cosa. Creo que esto es mejor que la ruta de partido.
Noah Clark
¿Qué es :approximate_ascii? No puedo encontrar documentación al respecto. Sin embargo, supongo que usa ASCII para aproximarse al carácter UTF-8, que ahora es el predeterminado. github.com/FriendlyId/friendly_id/blob/master/lib/friendly_id/…
d_rail
1
@page = Page.find(params[:id])debe cambiarse a @page = Page.find_by_id(params[:id])o simplemente obtendrá el 404 predeterminado (en público) en lugar de su 404. personalizado
d_rail
13

El enfoque n. ° 1 de Jeff (almacenar contenido en vistas y tener una ruta y una acción de controlador para cada página estática) es bueno. Lo único que agregaría es usar la controllermacro en sus rutas.

Entonces, en lugar de esto:

match '/home' => 'pages#home'
match '/about' => 'pages#about'
match '/contact' => 'pages#contact'

Puedes hacerlo:

controller :pages do
  get :home
  get :about
  get :contact
end

Son dos líneas adicionales, pero mucho más elegantes, ya que elimina la repetición y agrupa visualmente las rutas de las páginas estáticas.

También usa el getmétodo del verbo http en lugar de match, que es una mejor práctica para las rutas de Rails (y más conciso, ahora que Rails 4 requiere que se especifique el verbo http al usarmatch .

Richard Jones
fuente
6

El enfoque n. ° 1 de Jeff funciona muy bien para mí. Aquí hay un truco para hacer que el controlador busque páginas dinámicamente. Con esto, no es necesario tocar el controlador ni las rutas.rb para agregar páginas. Simplemente suelte las páginas en aplicación / vistas / páginas y el controlador las encontrará.

class PagesController < ApplicationController
  def show
    render params[:id]
  end
end
tiempo en
fuente
Esto funciona para mí, pero solo cuando tengo el partido o me meto en las rutas. ¿Hay algo más que deba hacerse para no tener que enumerar todas las rutas en route.rb? usando rieles 3.2.12
jrich
Siempre tenga cuidado con lo que hace con la entrada del usuario. No he probado esto, pero tengo renderacceso a todas las vistas, por lo que me preocuparía params[:id]que se vea así admin/whatever. FWIW, Rails renderizará automáticamente una vista sin crear una acción de controlador siempre que esa vista exista en la carpeta de vista que corresponde a su controlador. Todo lo que necesita hacer es agregar la ruta adecuada, lo cual no es gran cosa.
Richard Jones
6

Consulte http://railstutorial.org de Michael Hartl, que viene en una versión 2.3.8 y 3.0.x. Cubre esto con excelentes ejemplos y lo guía para construirlos desde el principio y también tendrá la oportunidad de aprender mucho más que este ejemplo. Lo recomiendo altamente.

traday
fuente
Esto ahora viene en una versión 3.2 y 4.0.
día
2

config / routes.rb

get ':id', to: 'pages#show'

app / controllers / pages_controller.rb

class PagesController < ApplicationController
  def show
    begin
      render params[:id]
    rescue ActionView::MissingTemplate
      render :file => "#{Rails.root}/public/404", :layout => false, :status => :not_found
    end
  end
end

Luego, coloque sus páginas estáticas en app / views / pages / {name} .html.erb (o cualquier formato de plantilla).

Owen
fuente
0

Una respuesta adecuada a su pregunta se vería básicamente como una introducción al marco de Rails: la estructura MVC, plantillas y enrutamiento DSL al menos. Jeff ha dado una buena puñalada, pero su respuesta aún asume una gran cantidad de conocimientos básicos sobre Rails de tu parte.

Sin embargo, sugiero que si su aplicación web es realmente así de simple, Rails podría ser excesivo. Buscaría algo más ligero, como Sinatra , que tiene una curva de aprendizaje mucho más baja que Rails y hace un gran trabajo en este tipo de cosas sin tener que lidiar con enrutamiento complejo, mapeo mágico de acción / plantilla MVC, etc.

Dave Sims
fuente
0

Sugeriría agregar sus páginas en la carpeta pública para que se sirvan directamente sin tener que pasar por rieles en absoluto. Sin embargo, no soy un experto, así que no estoy seguro de si esto podría tener algún inconveniente si la página es estática.

Ahmed Fathy
fuente
1
Sin embargo, esto se puede llamar una solución cruda. Esto no nos permitiría utilizar lo que proporciona Rails, especialmente el diseño de diseño común y el almacenamiento en caché de páginas . Sin embargo, no descartaría totalmente esta solución.
Sagar Ranglani
1
Esta técnica es muy rápida si tiene algo como Apache o Nginx configurado para servir las páginas de su publiccarpeta, pero renuncia a cualquier tipo de contenido dinámico en sus páginas, como una barra de navegación que muestra el estado de inicio / cierre de sesión del usuario.
Richard Jones