J'ai un contrôleur nommé 'companies' et plutôt que les URL de chaque entreprise étant désignées par un: id, j'aimerais que l'url utilise leur: name comme: url/company/Microsoft
au lieu de url/company/3
.
Dans mon contrôleur, je supposais que j'aurais
def show
@company = Company.find(params[:name])
end
Puisqu'il n'y aura aucun autre paramètre dans l'url, j'espérais Rails comprendrait que: nom a référencé la colonne: nom dans mon modèle d'entreprise. Je suppose que la magie ici serait dans la route mais je suis coincé à ce stade.
params
En fin de compte, vous cherchez la mauvaise solution - les clés de hachage params
sont plutôt hors de propos, vous devez être en mesure d'utiliser plus efficacement les données qu'elles contiennent.
Vos itinéraires seront construits comme:
#config/routes.rb
resources :controller #-> domain.com/controller/:id
Cela signifie que si vous demandez cet itinéraire: domain.com/controller/your_resource
, les params[:id]
la valeur de hachage sera your_resource
(peu importe si ça s'appelle params[:name]
ou params[:id]
)
-
La raison pour laquelle vous avez plusieurs réponses recommandant friendly_id
est parce que cela remplace la méthode find
de ActiveRecord
, vous permettant d'utiliser un slug
dans votre 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
vous pouvez éventuellement utiliser only:
ou except:
liste pour spécifier les itinéraires
et si vous voulez construire une URL, vous pouvez remplacer ActiveRecord :: Base # to_param d'un modèle associé:
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
les aides pour fonctionner correctement.
Remarque: je créerais une colonne de slug distincte pour le nom complexe, mais ce n'est que moi. C'est le cas simple.
class Company < ActiveRecord::Base
def to_param
name
end
end
Modifiez ensuite mes itinéraires param
pour plus de 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 je dois le chercher dans le bon sens.
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 le friendly_id à cet effet. Veuillez noter qu'il existe des différences entre friendly_id 4 et 5. Dans friendly_id 4, vous pouvez utiliser comme ceci
@company = Company.find(params[:id])
Cependant, vous ne pourrez pas faire cela dans friendly_id 5, vous devez utiliser:
@company = Company.friendly.find(params[:id])
Dans le cas où vous ne souhaitez pas utiliser les paramètres [: id] mais les paramètres [: nom], vous devez remplacer l'itinéraire dans routes.rb. Par exemple
get '/companies/:name', to: "companies#show"
J'espère que ces informations vous seront utiles
Il n'y a en fait pas de magie pour l'implémenter, vous devez soit le construire vous-même en implémentant correctement to_param
sur votre modèle (non recommandé) ou en utilisant l'un des joyaux disponibles pour cela comme:
J'utilise friendly_id
et il fait bien le travail.
Model.find (primary_key)
Le paramètre par défaut ici est l'identifiant de la clé primaire. Si vous souhaitez utiliser d'autres colonnes, vous devez utiliser Model.find_by_xxx donc ici cela pourrait être
def show
@company = Company.find_by_name(params[:name])
end