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 в моей модели. Я предполагаю, что магия здесь будет в пути, но я застрял в этой точке.
Ответы
Ответ 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