在rails中使用集合选择

时间:2018-01-24 18:00:52

标签: ruby-on-rails ruby

我正在尝试创建一个简单的博客应用程序。其中每个帖子都可以与标签相关联。这是我的观点

_form.hmtl.erb

<%= form.collection_select(:tag_ids, @tags, :id, :name, {}, :multiple => true) %> 

这是我的控制器

posts_controller.rb

 def new
    @post = @topic.posts.new
    @tag = @post.tags.new
    @tags = Tag.all
  end

  def create
    @post = @topic.posts.new(post_params)
    if @post.save
      redirect_to topic_posts_path
    else
      render 'new'
    end
  end
  def post_params
    params.require(:post).permit(:title,:content,:post_image, tag_ids: [])
  end
end

模型 Post.rb

 has_and_belongs_to_many :tags

我在帖子中创建新帖子&#34; NoMethodError时遇到错误#create&#34;,&#34; undefined method`map&#39;为零:NilClass&#34;。我无法找到错误的位置。

3 个答案:

答案 0 :(得分:2)

您应该有一个名为posts_tags.rb

的联接表
class Post_Tag < ApplicationRecord
  belongs_to :tag
  belongs_to :post
end

所以你已经有一些你想要选择的标签,并且帖子和联接表应该更新为post_idtag_id

在form_partial中更改此内容: -

<%= select_tag "tag_ids", options_for_select(@tags,:id,:name),{}, multiple: true%> <br/><br/>

注意: - 您不应该使用form.collection_select(:tag_ids...)这里form_for对象使用@post的原因,tag_ids不是@post对象的属性。< / p>

所以在提交表单时,您应该在params[:tag_ids]

中获取一系列标记ID
  def create
    @post = @topic.posts.new(post_params)
    if @post.save
      #create join table for tags that are associated with post
      @post.tags << Tag.find(params[:tag_ids]) 
      redirect_to topic_posts_path
    else
      render 'new'
    end
  end

所以在这里你可以得到

@post.tags =&gt;这将返回与帖子相关联的标签集合

答案 1 :(得分:0)

如果你正在使用这个场景,你必须在这两个模型之间建立许多关系。

  

has_and_belongs_to_many:tags

然后在形式上你应该使用

  

form.collection_select(:post,:tag_id,Tag.all,:id,:name_with_initial,prompt:true)

答案 2 :(得分:0)

控制器中的@tags操作中缺少create变量 - 您已在new中声明,但未在create中声明。如果保存不成功并且操作尝试重新呈现表单,则可能导致视图错误。

不确定是否全部,因为我不确定错误的确切位置。但正如您在其中一条评论中所说的那样 - 当您使用Tag.all代替@tags时,它会有效。