Route Controller# показывает метод, подобный тому, как Controller#index будет в Rails
Привет, ребята, я новичок в рельсах. Извините, если я не могу правильно определить этот вопрос.
То, что я хотел для:
domain.com/posts/1-sample-post
быть направленным вот так:
domain.com/1-sample-post
Как мне добиться этого на рельсовых маршрутах? Я пытался искать это почти 3 часа. Это очень просто в PHP-фреймворках. Я думал, что это легко и в Rails.
Я забыл упомянуть, что в моем приложении для моих статических страниц установлен гем High_voltage.
Сделал это:
#routes.rb
resources :posts
get '/:id' => 'posts#show'
Теперь мои страницы High_voltage не могут быть отображены.
Обновление решения:
Итак, вот что мы сделали на маршрутах:
Rails.application.routes.draw do
resources :authors
constraints(lambda { |req| Author.exists?(slug: req.params["id"]) }) do
get '/:id' => 'authors#show'
end
devise_for :users
resources :posts
constraints(lambda { |req| Post.exists?(slug: req.params["id"]) }) do
get '/:id' => 'posts#show'
end
end
Обратите внимание, что важно использовать только существует? запрос здесь, так как это очень быстро, чем другие методы, поэтому он не будет тратить так много времени на загрузку, чтобы сделать запись.
Отдельное спасибо ребятам ниже, которые очень помогли. Натанвда, Руольд и Тай.
2 ответа
Таким образом, другой ответ правильно предложил что-то вроде
get '/:id', to: 'posts#show'
Но это универсальный маршрут, и если другие маршруты не определены, он будет перехватывать все маршруты, в том числе и HighVoltage, если он настроен для обслуживания страниц в корневом каталоге. Теперь у вас есть два универсальных элемента: один для поиска статической страницы и один для поиска сообщения.
Лучшее решение в этом случае, imho, это сделать статические страницы явными (так как я предполагаю, что их будет не так много?)
get '/about' => 'high_voltage/pages#show', id: 'about'
get '/:id' => 'posts#show'
Если у вас много страниц, кажется, проще всего просто представить высокое напряжение на другом маршруте? Например, что-то вроде
get '/pages/:id' => 'high_voltage/pages#show'
get '/:id' => 'posts#show'
В обоих этих случаях, поскольку мы используем явную маршрутизацию, вам придется отключить маршрутизацию по умолчанию в высоковольтном инициализаторе:
# config/initializers/high_voltage.rb
HighVoltage.configure do |config|
config.routes = false
end
[ОБНОВЛЕНИЕ: добавить специальный контроллер для рассмотрения как сообщений, так и страниц]
Добавить HomeController
как это:
class HomeController < ApplicationController
# include the HighVoltage behaviour --which we will partly overwrite
include HighVoltage::StaticPage
def show
# try to find a post first
@post = Post.where(id: params[:id).first
if @post.present?
render 'posts/show'
else
# just do the high-voltage thing
render(
template: current_page,
locals: { current_page: current_page },
)
end
end
end
Конечно, я не тестировал этот код, но я думаю, что это должно помочь вам начать. Вместо рендеринга поста, вы также можете перенаправить на пост-контроллер, что может быть проще (и вы будете использовать PostsController
полностью), но добавляет редирект и изменит URL.
В вашем маршруте вы должны будете написать
get '/:id', 'home#show'
В вашем routes.rb
файл:
get '/:id-sample-post', to: 'posts#show', as: :sample_post
при условии, что posts
ваш контроллер и show
это действие, которое вызывает представление для вашей статьи с указанным идентификатором.
РЕДАКТИРОВАТЬ ПОСЛЕ КОММЕНТАРИИ OP: as: :sample_post
предложение должно создать помощника sample_post_path
это может быть вызвано как <%= link_to "Show", sample_post %>
,