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 %>,

Другие вопросы по тегам