Подтвердить что ты не робот

Rails маршрутизирует с: name вместо: id url parameters

У меня есть контроллер с именем "компании", а не URL-адреса для каждой компании, обозначаемой идентификатором: id. Я бы хотел, чтобы url использовал их: name, например: url/company/microsoft вместо url/company/3.

В моем контроллере я предположил, что у меня будет

 def show
   @company = Company.find(params[:name])
 end

Поскольку в URL-адресе не будет никаких других параметров, я надеялся, что рельсы поймут, что: name ссылается на столбец: name в моей модели. Я предполагаю, что магия здесь будет в пути, но я застрял в этой точке.

4b9b3361

Ответ 1

params

Суть в том, что вы смотрите на неправильное решение - хеш-ключи params не имеют отношения к делу, вам нужно более эффективно использовать данные, содержащиеся в них.

Ваши маршруты будут построены как:

#config/routes.rb
resources :controller #-> domain.com/controller/:id

Это означает, что если вы запросите этот маршрут: domain.com/controller/your_resource, хэш-значение params[:id] будет your_resource (не имеет значения, называется ли оно params[:name] или params[:id])

-

friendly_id

Причина, по которой у вас есть несколько рекомендаций, рекомендующих friendly_id, заключается в том, что это переопределяет метод find ActiveRecord, что позволяет использовать slug в ваш запрос:

#app/models/model.rb
Class Model < ActiveRecord::Base
  extend FriendlyId
  friendly_id :name, use: [:slugged, :finders]
end

Это позволяет сделать это:

#app/controllers/your_controller.rb
def show
    @model = Model.find params[:id] #-> this can be the "name" of your record, or "id"
end

Ответ 2

Хороший ответ с Rails 4.0+:

resources :companies, param: :name

необязательно вы можете использовать список only: или except: для указания маршрутов

и если вы хотите создать URL-адрес, вы можете переопределить ActiveRecord:: Base # to_param связанной модели:

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"

Ответ 3

Честно говоря, я просто перезаписал to_param в Модели. Это позволит корректным функциям company_path.

Примечание. Я бы создал отдельный столбец slug для сложного имени, но это только я. Это простой случай.

class Company < ActiveRecord::Base
  def to_param
    name
  end
end

Затем измените мои маршруты param для удобства чтения.

# The param option may only be in Rails 4+,
# if so just use params[:id] in the controller
resources :companies, param: :name

Наконец, в моем контроллере мне нужно найти правильный путь.

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

Ответ 4

Я рекомендую использовать friendly_id для этой цели. Обратите внимание, что между friendly_id 4 и 5. существуют различия. В friendly_id 4 вы можете использовать это как

 @company = Company.find(params[:id])

Однако вы не сможете это сделать в friendly_id 5, вы должны использовать:

 @company = Company.friendly.find(params[:id])

Если вы не хотите использовать params [: id], но params [: name], вам необходимо переопределить маршрут в route.rb. Например

 get '/companies/:name', to: "companies#show"

Надеемся, что эта информация вам поможет.

Ответ 5

На самом деле нет волшебства для реализации этого, вы должны либо построить его самостоятельно, правильно внедряя to_param в вашу модель (не рекомендуется), либо используя один из драгоценные камни для этого типа:

Я использую friendly_id, и он отлично выполняет работу.

Ответ 6

Model.find(primary_key)
Здесь используется параметр primary_key. Если вы хотите использовать другие столбцы, вы должны использовать Model.find_by_xxx поэтому здесь может быть

def show
  @company = Company.find_by_name(params[:name])
end