Нет совпадений маршрута {: действие=> «показать», : контроллер=>»категории», : url=>»»»}, отсутствуют обязательные ключи: [:url]

#ruby-on-rails #ruby

#ruby-on-rails #ruby

Вопрос:

Я немного новичок в rails. итак, я пытаюсь сделать клон craigslist. пока что я реализовал все категории и подкатегории. Я столкнулся с этой ошибкой, когда попытался оптимизировать свои URL-ссылки, чтобы они могли быть похожи на этот craigslist-clone / c / community / activities / 3, где «сообщество» является родительской категорией, а «действия» — подкатегорией, и, следовательно, «3» — это сообщение, в котором.

теперь я могу нажимать на каждую родительскую категорию без ошибок. единственный раз, когда я получаю ошибку, это когда я нажимаю на подкатегорию, и ошибка выглядит следующим образом:

 No route matches {:action=>"show", :controller=>"categories", :url=>""}, missing required keys: [:url]

  <% category.subcategories.limit(10).each do |subcategory| %>
               <div class= "subcat"><%= link_to subcategory.name, show_category_path(subcategory.url) %></div>
           <%end%> 

           </div>
  

Мой categories_controller :

 class CategoriesController < ApplicationController
  before_action :set_category, only: [:show, :edit, :update, :destroy]

  # GET /categories
  # GET /categories.json
  def index
    @categories = Category.all
  end

  # GET /categories/1
  # GET /categories/1.json
  def show
    category_ids = @category.subcategories.ids
    category_ids << @category.id
    @posts = Post.where(category_id: category_ids)

  end

  # GET /categories/new
  def new
    @category = Category.new
  end

  # GET /categories/1/edit
  def edit
  end

  # POST /categories
  # POST /categories.json
  def create
    @category = Category.new(category_params)

    respond_to do |format|
      if @category.save
        format.html { redirect_to @category, notice: 'Category was successfully created.' }
        format.json { render :show, status: :created, location: @category }
      else
        format.html { render :new }
        format.json { render json: @category.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /categories/1
  # PATCH/PUT /categories/1.json
  def update
    respond_to do |format|
      if @category.update(category_params)
        format.html { redirect_to @category, notice: 'Category was successfully updated.' }
        format.json { render :show, status: :ok, location: @category }
      else
        format.html { render :edit }
        format.json { render json: @category.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /categories/1
  # DELETE /categories/1.json
  def destroy
    @category.destroy
    respond_to do |format|
      format.html { redirect_to categories_url, notice: 'Category was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_category
      @category = Category.find_by_url(params[:url])
    end


    # Only allow a list of trusted parameters through.
    def category_params
      params.fetch(:category, {})
    end
end
  

Мой home.html.erb — это :

             <div class="row">
            <% @categories.each do |category| %>
            <div class="col-4 mb-4 category-box">
            <p class="h6"><strong><%= link_to category.name, show_category_path(category.url), class: "text-dark" %></strong></p>

            <% category.subcategories.limit(10).each do |subcategory| %>
                <div class= "subcat"><%= link_to subcategory.name, show_category_path(subcategory.url) %></div>
            <%end%> 

            </div>
            <% end %> 
  

routes.rb

   devise_for :accounts
  resources :posts
  resources :categories, except:[:show]
  get "c/:url" => "categories#show", as: :show_category
  post "message/send" => "public#send_enquiry_to_user", as: :send_enquiry
  get "/scams" => "public#scams", as: :scams
  get "/terms" => "public#terms", as: :terms
  get "/safety" => "public#safety", as: :safety
  get "/faqs" => "public#faqs", as: :faqs
   devise_scope :account do
     get "/accounts/sign_out" => "devise/sessions#destroy"
   end
  root to: "public#home"
end```
  

моя категория.Модель rb :

 class Category < ApplicationRecord
    belongs_to :parent, class_name:"Category", optional: true
    has_many :subcategories, class_name:"Category", foreign_key: :parent_id, dependent: :destroy
    has_many :posts
end
  

моя таблица категорий :

   create_table "categories", force: :cascade do |t|
    t.string "name"
    t.string "url"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.integer "parent_id"
  end
  

Я просто чувствую, что зашел в тупик, любая помощь или любая рекомендация ресурса, который мне может понадобиться прочитать, чтобы преодолеть эту проблему, высоко ценится. Спасибо!

Ответ №1:

Вы определили пользовательский маршрут следующим образом:

 get "c/:url" => "categories#show", as: :show_category
  

Поэтому вам необходимо явно передать url ключ методу route, например:

 show_category_path(url: category.url)
  

Вы также могли бы, в качестве альтернативы, переопределить именованный параметр маршрута вместо использования связанного параметра. Другими словами, вы могли бы определить маршрут, используя что-то вроде этого:

 resources :categories, path: "c", only: :show, param: :url
  

Это генерирует следующий маршрут, и ваш исходный код будет с ним работать нормально:

 category GET     /c/:url(.:format)    categories#show
  

Комментарии:

1. итак, я явно передал URL-ключ методу route, но, похоже, я все еще не могу щелкнуть без ошибок ни в одной из подкатегорий. Я получаю сообщение об ошибке, в котором говорится, no route matches [GET] "/c" я хочу, чтобы мой URL был таким, когда я нажимаю на подкатегорию: ‘/ сообщество / деятельность / 3’ нужно ли мне сгенерировать новый маршрут?

2. @HaithamMaryan Вы получаете ошибку, потому что ваш subcategory.url == nil ? Вы не поделились ни своим кодом, ни своими данными, поэтому я действительно просто догадываюсь, в чем может быть ошибка.

3. Если вам нужен другой маршрут (возможно, с другим поведением?) Для URL-адресов подкатегорий, тогда да, вам нужно будет определить это как отдельный маршрут в config/routes.rb .

Ответ №2:

У одного из вас subcategory , похоже, пустой URL.

 <% category.subcategories.limit(10).each do |subcategory| %>
  <% next if subcategory.url.blank? %>
  <div class= "subcat"><%= link_to subcategory.name, show_category_path(subcategory.url) %></div>
<% end %> 
  

Комментарии:

1. теперь, после того, как я вставил этот блок кода, я, похоже, не вижу никаких подкатегорий на своей домашней странице. Я вижу только родительские категории @ErvalhouS

2. В моем вопросе я прикрепил CategoryModel и таблицу категорий

Ответ №3:

Итак, я уже сталкивался с подобной проблемой раньше, и вы можете захотеть изменить свой resource маршрут с помощью :path опции, и это может помочь.

 devise_for :accounts
  resources :posts
  resources :categories, path: "c", except:[:show] do
   get "/:url" => "categories#show", as: :show_category
  end

  post "message/send" => "public#send_enquiry_to_user", as: :send_enquiry
  get "/scams" => "public#scams", as: :scams
  get "/terms" => "public#terms", as: :terms
  get "/safety" => "public#safety", as: :safety
  get "/faqs" => "public#faqs", as: :faqs
   devise_scope :account do
     get "/accounts/sign_out" => "devise/sessions#destroy"
   end
  root to: "public#home"
end
  

или вы также можете просто явно передать :url своему помощнику по маршруту, например show_category_path(url: category.url)