如何让我的对象不那么混乱?

时间:2016-07-13 15:50:14

标签: ruby-on-rails erb

我的项目有三个主要部分:

  • 页面(类似文章)
  • 类别(页面有与之关联的类别)
  • 标签(每个页面可以有多个不同的标签)

我有一个侧边栏,它使用@categories来浏览项目中所有当前类别的列表:

<div class="col-md-3">
  <p class="lead">Categories</p>
  <div class="list-group">
    <%= link_to 'All articles', pages_path(@page), :class => 'list-group-item' %>
    <% @categories.each do |category| %>
      <%= link_to category.name, category_path(category), :class => 'list-group-item' %>
    <% end %>
  </div>
</div>

但目前我需要加入

@categories = Category.all

在我的索引和我的控制器中显示页面和类别的操作,以便侧边栏加载(我只在项目的这两个部分使用侧边栏)。

有没有比在控制器中的每个操作中包含上述代码更简单的方法?

在创建页面并转到标记的显示页面以查看与这些标记相关联的任何页面后,还使用标记控制器,我收到错误消息“无法找到& #39; ID&#39; = 2。

class TagsController < ApplicationController

def index
    @tags = Tag.all
end

def show
    @tag = Tag.find(params[:id])
    @page = Page.find(params[:id])
    @categories = Category.all
end

-

<% @tag.pages.each do |page| %>
  <div class="thumbnail">
    <div class="text">
      <article class="clearfix">
        <%= link_to page.title, url_for_page(page), class: "h1" %>
        <p class="pull-right"><span class="glyphicon glyphicon-time"></span> Posted on <%= page.created_at.to_formatted_s :long %></p>
        <hr />
        <%= page.body.html_safe %>
        <hr />
        <div class="btn-group btn-group-xs" role="group" aria-label="...">
          <% page.tags.each do |tag| %>
            <%= link_to tag.name, tag_path(tag), class: "btn btn-info" %>
          <% end %>
        </div>
      </article>
    </div>
  </div>
<% end %>

有人有任何想法吗?任何帮助将不胜感激:)

谢谢!

更新

路由文件:

Rails.application.routes.draw do
  resources :categories
  resources :pages
  resources :tags

型号:
Category.rb

class Category < ActiveRecord::Base
    has_many :pages

Page.rb

class Page < ActiveRecord::Base
    include Bootsy::Container
    belongs_to :category
    has_many :taggings
    has_many :tags, through: :taggings

    def tag_list
        self.tags.collect do |tag|
            tag.name
        end.join(", ")
    end

    def tag_list=(tags_string)
        tag_names = tags_string.split(", ").collect{ |s| s.strip.downcase }.uniq
        new_or_found_tags = tag_names.collect { |name|         Tag.find_or_create_by(name: name) }
        self.tags = new_or_found_tags
    end
end

Tag.rb

class Tag < ActiveRecord::Base
    include Bootsy::Container
    has_many :taggings
    has_many :pages, through: :taggings

    def to_s
        name
    end
end

Tagging.rb

class Tagging < ActiveRecord::Base
    include Bootsy::Container   
  belongs_to :tag
  belongs_to :page
end

2 个答案:

答案 0 :(得分:0)

您可以为控制器添加仅限于索引和显示操作的before_action,如下所示:

class TagsController < ApplicationController
  before_action :load_categories, only: [:index, :show]

  # Your code

  private

  def load_categories
    @categories = Category.all
  end
end     

这会将类别加载到index和show动作的实例变量中。

对于你得到的错误,如果我正确地阅读它你有嵌套路线?您需要获取标记的正确ID,即:tag_id:

def show
  @tag = Tag.find(params[:tag_id])
  @page = Page.find(params[:id])
  @categories = Category.all
end

你得到了:两者的身份证明。如果这不起作用,您的路线是否嵌套?如果没有发布你的路线,我会更新答案。

答案 1 :(得分:0)

您可以DRY控制器在回调中设置页面和类别。但请注意:您可以在类别#index action中省略类别查询,但您的页面#...操作可能会跳过所有skip_before_action set_page的回调或更好地覆盖该方法并使用正确的处理。

class ApplicationController
  before_action set_page, only: [:index, :show]
  before_action set_categories, only: [:index, :show]

  private
  def set_page
   @page = Page.find params[:page_id]
  end

  def set_categories
   @categories = Category.all
  end
end