【问题标题】:Create a Post_category for a Post a choose my post with collection post_category为帖子创建一个 Post_category a 选择我的带有集合 post_category 的帖子
【发布时间】:2016-04-19 20:06:00
【问题描述】:

我创建了一个 post_category 表来为具体帖子添加一个类别。

例如,我将 post_categories 创建为国家,如日本或中国。我想创建来自日本或中国等国家的文化或模式的帖子。我现在只关注 post_categories 作为国家,下面是我所做的代码。

我创建了这个PostCategory,这里是迁移和模型

 create_table "post_categories", force: :cascade do |t|
    t.string   "name"
    t.string   "description"
    t.datetime "created_at",  null: false
    t.datetime "updated_at",  null: false
  end

class PostCategory < ActiveRecord::Base
  has_many :posts, dependent: :destroy

  NAMES = ["Japon", "Chine", "Corée du Sud", "Moyen Orient", "Indien"]
  validates :name, inclusion: { in: PostCategory::NAMES, allow_nil: false }
end

我用PostCategory外键创建了一个Post,这里是迁移和模型

  create_table "posts", force: :cascade do |t|
    t.string   "cover"
    t.string   "subtitle"
    t.string   "title"
    t.text     "introduction"
    t.text     "body"
    t.text     "conclusion"
    t.string   "tag"
    t.string   "source"
    t.string   "link"
    t.integer  "user_id"
    t.datetime "created_at",       null: false
    t.datetime "updated_at",       null: false
    t.integer  "post_category_id"
  end

class Post < ActiveRecord::Base
  belongs_to :user

  belongs_to :post_category, dependent: :destroy

  TAGS = ["Design", "Mode", "Tendance", "Life-Style", "Tradition", "Gastronomie", "Insolite", "Technologie"]
  validates :tag, inclusion: { in: Post::TAGS, allow_nil: false }

  mount_uploader :cover, ImageUploader
end

我想用一个简单的表单集合创建一个类别,我希望我将显示在post show#view

这里是post_categories controller

class PostCategoriesController < ApplicationController
   # before_action :set_post_category, only: [:show, :new, :create, :destroy]

  def show
    @post_category = PostCategory.find(params[:id])
  end

  def index
    @post_categories = PostCategory.all
  end

  def create
    @post_category = post_categories.new(post_category_params)
    if @post_category.save
      redirect_to @post
    else
      render 'post_categories/show'
    end
  end

  def new
    @post_category = PostCategory.new
  end

  def edit
  end

  def update

  end

  def destroy
    @post_category = PostCategory.find(params[:id])
    @post_category.destroy
    redirect_to post_path(@post)
  end

  private

  # def set_post
  #   @post = Post.find(params[:post_id])
  # end

   def find_post_category
    @post_category = PostCategory.find(params[:id])
  end

  def post_category_params
    params.require(:post_category).permit(:name, :description)
  end
end

这里是posts controller

class PostsController < ApplicationController

  before_filter :authenticate_user!, except: [:index, :show]
  before_action :find_post, only: [:show, :edit, :update, :destroy]

  def index
    @posts = Post.all
  end

  def show
    # @alert_message = "Vous lisez #{@post.title}"
  end

  def new
    # if current_user and current_user.admin?
      @post = Post.new
    # else
    #   redirect_to posts_path
    # end
  end

  def create
    # if current_user and current_user.admin?
     @post = @post_category.posts.new(post_params)
      #@post = current_user.posts.new(post_params)
      if @post.save
        redirect_to @post
      else
        render :new
      end
    # else
    #   render 'shared/404.html.erb'
    # end
  end

  def edit
  end

  def update
    if @post.update(post_params)
      redirect_to @post
    else
      render :edit
    end
  end

  def destroy
    @post.destroy
    redirect_to :back
  end

  private

  # def find_post
  #   @post = Post.find(params[:id])
  # end

  def set_post_category
    @post_category = PostCategory.find(params[:post_category_id])
  end

  def post_params
    params.require(:post).permit(:title, :subtitle, :introduction, :body, :cover, :tag, :post_category_id)

  end
end

我不知道我可以创建哪些视图以及如何调用post new#view,因为我配置了这样的路由,我需要一个post_category_id

resources :post_categories do
    resources :posts
  end

那是我必须使用下面的path

 post_category_posts GET      /post_categories/:post_category_id/posts(.:format)          posts#index
                              POST     /post_categories/:post_category_id/posts(.:format)          posts#create
       new_post_category_post GET      /post_categories/:post_category_id/posts/new(.:format)      posts#new
      edit_post_category_post GET      /post_categories/:post_category_id/posts/:id/edit(.:format) posts#edit
           post_category_post GET      /post_categories/:post_category_id/posts/:id(.:format)      posts#show
                              PATCH    /post_categories/:post_category_id/posts/:id(.:format)      posts#update
                              PUT      /post_categories/:post_category_id/posts/:id(.:format)      posts#update
                              DELETE   /post_categories/:post_category_id/posts/:id(.:format)      posts#destroy
              post_categories GET      /post_categories(.:format)                                  post_categories#index
                              POST     /post_categories(.:format)                                  post_categories#create
            new_post_category GET      /post_categories/new(.:format)                              post_categories#new
           edit_post_category GET      /post_categories/:id/edit(.:format)                         post_categories#edit
                post_category GET      /post_categories/:id(.:format)                              post_categories#show
                              PATCH    /post_categories/:id(.:format)                              post_categories#update
                              PUT      /post_categories/:id(.:format)                              post_categories#update
                              DELETE   /post_categories/:id(.:format)                              post_categories#destroy

我想在我的 show#view 帖子中添加类别并创建多搜索访问以查找添加到特定类别的帖子。谢谢你的帮助

【问题讨论】:

  • 我认为您的路线提取之前的句子是您问题的关键部分,但它对我没有任何意义 - 您能改写它吗?
  • @FrederickCheung 是的,我想在我的帖子显示#view 中调用 post_category 并创建一个搜索栏来查找此类别的帖子

标签: ruby-on-rails methods controller


【解决方案1】:

你设置关系的方式有一个很大的缺陷——一个帖子只能属于一个类别,因为 id 存储在帖子表中。

相反,您通常会使用多对多关系:

class Post < ActiveRecord::Base
  has_many :categories, :categories
  has_many :post_categories
end

class Category < ActiveRecord::Base
  has_many :posts
  has_many :posts, through: :categories
end

class Categorization < ActiveRecord::Base
  belongs_to :post
  belongs_to :category
  validates_uniqueness_of :category_id, scope: :post_id
end

这里categorizations 表充当连接表,将PostCategory 链接在一起 - 帖子可以有任意数量的类别,反之亦然。


添加:

要创建连接模型和迁移以创建表,您需要执行以下操作:

rails g model Categorization post:belongs_to category:belongs_to

在生成器中使用默认为post_idcategory_id创建外键。

您可能还想在迁移中添加复合唯一性约束。

def change 
  # ...
  add_index(:categorizations, [:post_id, :category_id], unique: true)
end

您的CategoriesController 走在正确的轨道上,但我不会使用嵌套路由来创建帖子。相反,您可能只想使用普通的旧 Rails 控制器并让用户通过复选框选择类别:

<%= form_for(@post) do |f| %>
  <%= f.collection_check_boxes :category_ids, Category.all, :id, : name %>
<% end %>

然后您将category_ids 参数添加到白名单:

  def post_params
    params.require(:post)
          .permit(:title, :subtitle, :introduction, 
                  :body, :cover, :tag, category_ids: []
                 )

  end

奇怪的category_ids: [] 语法是因为我们希望允许一个标量值数组。

按 id 从类别中查询帖子可以这样完成:

Post.joins(:categories).where(category: 1)

您甚至可以通过传递一个数组来选择多个类别:

Post.joins(:categories).where(category: [1, 2, 3])

要从视图中将其连接在一起,您可以使用带有复选框或选择的链接(用于单个类别)或表单(是的表单可用于 GET)。

处理文本输入有点棘手。一个天真的实现是:

Post.joins(:categories).where(category: { name: params[:search_query] })

但是,用户输入必须完全匹配。有几个 gem 可以为活动记录提供搜索功能。不过,我会等到您有更多经验后再使用该功能,因为实施起来可能会很棘手。

见:

【讨论】:

  • 我要为帖子创建类别外键
  • “分类”表中没有外键。
  • 我改变了我的策略,我们可以在聊天中谈谈我的代码吗?我需要一个外部视图。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-20
  • 1970-01-01
  • 2019-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多