Не удалось найти категорию без идентификатора для Rails Blog - PullRequest
0 голосов
/ 16 марта 2019

У меня возникают проблемы при создании категорий для моего блога. ActiveRecord :: RecordNotFound в ArticlesController # index

Это код файла rout.rb

Rails.application.routes.draw do
  resources :categories
#  get 'sessions/new'

  resources :sessions
  resources :users
  get 'welcome/index'

  resources :articles do
    resources :comments
    collection do
      get :search #creates a new path for searching
    end
  end
  resources :subscribers
  root 'welcome#index'
  get 'pages/about' => 'application#show'
end

Это код файла article_controller.rb

class ArticlesController < ApplicationController

before_action :admin_authorize, :except => [:index, :show, :search]

  def index
    if params[:category].blank?
      @articles = Article.all.order("created_at DESC")
    else
      @category_id = Category.find_by(name: params[:category]).id
      @articles = Article.where(category_id: @category_id).order("created_at DESC")
    end
  end

  def new
    @article = Article.new
    @categories = Category.all.map{|c| [c.name, c.id]}
  end

  def show
    @article = Article.find(params[:id])
  end

  def create
    @article = Article.new(article_params)
    @article.category_id = params[:category_id]

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

  def edit
    @article = Article.find(params[:id])
    @categories = Category.all.map{|c| [ c.name, c.id ] }
  end

  def search
    if params[:search].blank?
      @articles = Article.all
    else
      @articles = Article.search(params)
    end
  end

  def update
    @article = Article.find(params[:id])
    @article.category_id = params[:category_id]
    if @article.update(article_params)
      redirect_to @article
    else
      render 'edit'
    end
  end

  def destroy
    @article = Article.find(params[:id])
    @article.destroy
    redirect_to articles_path
  end

private
  def article_params
    params.require(:article).permit(:title, :text, :search, :music, :movie, :photo)
  end

  def find_article
    @article = Article.find(params[:id])
  end
end

А вот файл представления индекса статьи: (где ошибка)

<div class="row">
<div class="col"></div>
<div class="col-md-10">
<h1>List of all Articles</h1>
<% if current_user && current_user.admin? %>
<p>
  <%= link_to 'Create New Article', new_article_path, class:'btn btn-lg btn-info' %>
</p>
<% end %>
<table class="table table-hover table-striped table-responsive-xs">
<thead>
<tr>
  <th>Photo</th>
  <th>Date</th>
  <th>Title</th>
  <th>Text</th>
<% if current_user && current_user.admin? %>
  <th colspan="3">Editing Options</th>
<% else %>
  <th colspan="1">Show Articles</th>
<%end%>
</tr>
</thead>
<tbody>
<% @articles.each do |article| %>
<tr>
  <td>
    <% if article.photo.present? %>
    <%= image_tag article.photo.url(:thumb) %>
    <% else %>
    <%= image_tag('noimage.jpg', style:"width:50px;") %>
    <% end %>
  </td>
  <td>
    <%= article.created_at.strftime('%d/%m/%Y')%>
  </td>
  <td>
    <%= article.title %>
  </td>
  <td>
    <%= truncate(article.text, length: 75) %>
  </td>
  <td>
    <%= link_to Category.find(article.category_id).name, category_path(article.category_id) %>
  </td>
  <td>
    <%= link_to 'Show', article_path(article), class:'btn btn-sm btn-info' %>
  </td>
  <% if current_user && current_user.admin? %>
  <td>
    <%= link_to 'Edit', edit_article_path(article), class:'btn btn-sm btn-warning' %>
  </td>
  <td>
    <%= link_to 'Delete', article_path(article),
        class: 'btn btn-sm btn-danger',
        method: :Delete,
        data: {confirm: "Are you sure???"}%>
  </td>
  <% end %>
</tr>
<% end %>
</tbody>
</table>
<p>
  <%= link_to 'Home', welcome_index_path, class:'btn btn-md btn-warning' %>
</p>
</div>
<div class="col"></div>
</div>

В моем окне браузера я вижу эту проблему в этом фрагменте кода представления статьи:

<% @articles.each do |article| %>
and 
<%= link_to Category.find(article.category_id).name, category_path(article.category_id) %>

1 Ответ

0 голосов
/ 16 марта 2019

У вас есть учебник N + 1 вопрос , плюс, что article.category необязательно, так что вы звоните Category.find(nil).name.

При условии, что вы установили связь 1-ко-многим между статьей и категорией

class Category
  has_many :articles
end

class Article
  belongs_to :category
end

Прежде всего, убедитесь, что вы загружаете категорию вместе со статьями:

class ArticlesController < ApplicationController
  def index
    @articles = Article.includes(:category).order(created_at: :desc)
  end
end

Тогда, когда вы перебираете представление, просто используйте article.category.

<% if article.category %>
  <%= link_to article.category.name, article.category %>
<% end %>

Вам не нужно явно передавать category_path(article.category_id). Просто передайте запись, и Rails достаточно умен, чтобы понять это самостоятельно.

Я бы также настроил отдельный контроллер для обработки статей, вложенных в категорию:

# config/routes.rb
resources :categories do
  resources :articles, only: [:index], module: :categories
end

# app/controllers/categories/articles_controller.rb
module Categories
  class ArticlesController
    before_action :set_category

    # GET /categories/:category_id/articles
    def index
      @articles = @category.articles.order(created_at: :desc)
    end

    def set_category
      @category = Category.includes(:articles).find(params[:category_id])
    end
  end
end

Имеет меньшую циклическую сложность и соответствует SRP . Тот факт, что контроллеры отображают другое представление, также является плюсом, поскольку позволяет настраивать представление для различных контекстов. При необходимости используйте партиалы для обмена кодом.

Вы можете связать его с:

<%= link_to "Articles in #{category.name}", [category, :articles] %>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...