2 votes

Acheminement étrange

Comment puis-je configurer mon application rails pour répondre à de telles urls :

http://mydomain.com/white-halogene-lamp

http://mydomain.com/children-lamps

http://mydomain.com/contact-form

Le premier doit être lié au contrôleur de mes produits, et afficher mon produit avec ce nom.

Le second doit être lié à mon contrôleur de catégories et afficher la catégorie portant ce nom.

Le troisième doit être lié au contrôleur de mon site, et montrer le site avec ce titre.

Les trois modèles (produit, catégorie, site) ont une méthode to_seo, donnant les urls mentionnées ci-dessus (après le slash)

Je sais que ce n'est pas la voie la plus reposante, mais s'il vous plaît ne discutez pas ici, c'est une mauvaise approche ou pas, ce n'est pas la question.

La question est de savoir comment réaliser ce routage bizarre ?

Je sais que nous avons des itinéraires de capture, mais comment puis-je dire à rails d'utiliser différents contrôleurs sur différentes urls dans l'itinéraire de capture ? Ou avez-vous une meilleure idée ?

J'éviterais les redirections vers d'autres urls.

3voto

Peteris Points 355

C'est un peu bizarre, surtout si les redirections sont hors de question, mais une façon de répondre à ce besoin pourrait être de remplir le mappage des routes à partir de vos tables - routes.rb est juste un autre morceau de code ruby, donc si vous pouvez mettre

map.connect 'children-lamps', :controller => 'category', :action => 'show',  :id => 123

ou de n'importe quelle autre façon de le définir dans routes.rb, alors vous pouvez aussi bien mettre

Category.each { |category|
  map.connect category.to_seo, :controller => 'category', :action => 'show', :id => category.id
}

mais cela ne fonctionnerait que si vos catégories/sites sont statiques.

1voto

Arcath Points 1056

Le meilleur moyen est d'ajouter une autre couche, et d'exécuter les routes comme ceci :

http://yoursite.com/products/white-halogene-lamp

comme cela peut être fait avec :

map.product_seo "prodcuts/:product", :controller => :products, :action => :show

puis dans Produits#Montrer le changement @product=Product.find(params[:id]) à :

@product=Product.find_by_name(params[:product]) if params[:product] #This assumes name is the field you are searching on
@product=Product.find(params[:id]) unless params[:product]

De cette façon, les anciennes routes fonctionnent toujours, mais vous obtenez également des urls de référencement.

pour les catégories, il suffit de répéter et de modifier si nécessaire (l'url serait /categorys/children-lamps)

pour le contrôleur de sites, vous avez vraiment besoin de la même chose, sans que le niveau supérieur ne dise ce que vous voulez, vous devriez définir chaque route manuellement.

0voto

Sven Koschnicke Points 2351

Vous pouvez utiliser les contraintes de route pour cela.

class ProductExistsConstraint

  def matches?(request)
    Product.exists? :slug => request.path_parameters['slug']
  end

end

et des classes similaires pour les catégories et les pages. Ensuite, dans les routes

match ":slug" => "products#show", :constraints => ProductExistsConstraint.new
match ":slug" => "categories#show", :constraints => CategoryExistsConstraint.new
match ":slug" => "page#show", :constraints => PageExistsConstraint.new

Je ne l'ai pas testé, mais je pense que c'est au moins une indication dans la bonne direction. Voir aussi ici : http://guides.rails.info/routing.html#advanced-constraints

0voto

Oscar Del Ben Points 3200

J'ai dû faire quelque chose de très similaire. Vous pouvez simplement configurer une action de poignée générique comme ceci :

def handle
  @product = Product.find_by_permalink params[:permalink]
  if product
    return render_product
  end

  @category - Category.find_by_permalink
  ..
end

private

def render_product
  # something like this.
  render :file => 'products/show'
end

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X