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.

21
demandé sur zishe 2014-06-15 07:49:38

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])

--

friendly_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
11
répondu Richard Peck 2014-06-15 06:24:32

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"
61
répondu Matrix 2017-03-07 07:17:19

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
10
répondu Azolo 2016-08-23 22:12:30

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

6
répondu The Lazy Log 2014-06-15 04:22:44

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.

5
répondu Maurício Linhares 2014-06-15 04:04:06

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
2
répondu brick 2014-06-15 04:06:28