Rails routes avec:nom au lieu de: ID paramètres d'url
j'ai un controller nommé 'companies' et plutôt que les urls de chaque compagnie étant dénotées avec un :id, j'aimerais que l'url utilise leur :name tel que: url/company/microsoft
au lieu de url/company/3
.
dans mon contrôleur j'ai supposé que j'aurais
def show
@company = Company.find(params[:name])
end
Puisqu'il n'y aura pas d'autre paramètre dans l'url, j'espérais que les rails comprendraient que :nom renvoie à la colonne :Nom dans mon modèle D'entreprise. Je suppose que la magie ici serait dans la route mais je suis coincé à ceci point.
6 réponses
params
le résultat est que vous cherchez la mauvaise solution - la params
clés de hachage sont plutôt pertinent, vous devez être en mesure d'utiliser les données contenues à l'intérieur d'eux plus efficacement.
vos routes seront construites comme:
#config/routes.rb
resources :controller #-> domain.com/controller/:id
cela signifie que si vous demandez cette route:domain.com/controller/your_resource
, le params[:id]
valeur de hachage sera your_resource
(n'a pas d'importance si elle est appelée params[:name]
ou params[:id]
)
--
La raison pour laquelle vous avez plusieurs réponses recommander friendly_id
est parce que cela l'emporte sur le find
méthode ActiveRecord
, vous permettant d'utiliser un slug
dans ta requête:
#app/models/model.rb
Class Model < ActiveRecord::Base
extend FriendlyId
friendly_id :name, use: [:slugged, :finders]
end
Cela vous permet de faire ceci:
#app/controllers/your_controller.rb
def show
@model = Model.find params[:id] #-> this can be the "name" of your record, or "id"
end
Bonne réponse avec Rails 4.0+ :
resources :companies, param: :name
optionnellement, vous pouvez utiliser only:
ou except:
liste de préciser les itinéraires
et si vous voulez construire une URL, vous pouvez outrepasser ActiveRecord:: Base#to_param d'un model apparenté:
class Video < ApplicationRecord
def to_param
identifier
end
# or
alias_method :to_param, :identifier
end
video = Video.find_by(identifier: "Roman-Holiday")
edit_videos_path(video) # => "/videos/Roman-Holiday"
honnêtement, je voudrais juste écraser le to_param
dans le Modèle. Cela permettra à company_path
aide à travailler correctement.
Note: je créerais une colonne de limaces séparée pour les noms complexes, mais ce n'est que moi. C'est le cas simple.
class Company < ActiveRecord::Base
def to_param
name
end
end
puis changer mes routes param
pour la lisibilité.
# The param option may only be in Rails 4+,
# if so just use params[:id] in the controller
resources :companies, param: :name
Enfin dans mon Controller il faut que je regarde de la bonne façon.
class CompaniesController < ApplicationController
def show
# Rails 4.0+
@company = Company.find_by(name: params[:name])
# Rails < 4.0
@company = Company.find_by_name(params[:name])
end
end
je recommande d'utiliser friendly_id à cet effet. Veuillez noter qu'il y a des différences entre friendly_id 4 et 5. Dans friendly_id 4, Vous pouvez utiliser comme ceci
@company = Company.find(params[:id])
Toutefois, vous ne serez pas en mesure de le faire dans friendly_id 5, vous devez utiliser:
@company = Company.friendly.find(params[:id])
dans le cas où vous ne voulez pas utiliser les params[:id] mais les params[:name], vous devez outrepasser la route dans les routes.RB. Par exemple,
get '/companies/:name', to: "companies#show"
J'espère que ces informations seront utiles pour vous
il n'y a en fait aucune magie pour mettre en œuvre cela, vous devez soit construire vous-même en implémentant correctement to_param
à votre modèle (Non recommandé) ou en utilisant l'une des gemmes disponibles pour cela comme:
j'utilise friendly_id
et il fait le travail très bien.
Modèle.trouver(primary_key)
Le paramètre par défaut ici est primary_key id.
Si vous souhaitez utiliser d'autres colonnes, vous devez utiliser le Modèle.find_by_xxx
donc, ici, il pourrait être la
def show
@company = Company.find_by_name(params[:name])
end