M:N Rails 中的关系错误

M:N relation error in Rails

我在尝试通过 m : n

在 Post 和 Hashtag 之间建立关系时遇到了一些错误

一切正常,但是当尝试像这样保存日志打印时

Started POST "/posts" for 127.0.0.1 at 2018-03-05 21:43:00 +0900
Processing by PostsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"DxRb+4PAfOsDTCEMx+BcBNKK/LWAH5NxwVh6n7OChtwBL/svUQVEBj7mrWdCYB2BIUHO/Gql9UC6mKLMMoPqEg==", "post"=>{"title"=>"please", "content"=>"please!!!!!", "hashtags_attributes"=>{"0"=>{"title"=>"hash1"}, "1"=>{"title"=>"hash2"}, "2"=>{"title"=>"hash3"}}}, "commit"=>"Create Post"}
Unpermitted parameter: hashtags_attributes
Unpermitted parameters: title, content
  Hashtag Load (0.2ms)  SELECT  "hashtags".* FROM "hashtags" WHERE "hashtags"."title" = ? LIMIT ?  [["title", "hash1"], ["LIMIT", 1]]
Unpermitted parameters: title, content
  Hashtag Load (0.1ms)  SELECT  "hashtags".* FROM "hashtags" WHERE "hashtags"."title" = ? LIMIT ?  [["title", "hash2"], ["LIMIT", 1]]
Unpermitted parameters: title, content
  Hashtag Load (0.1ms)  SELECT  "hashtags".* FROM "hashtags" WHERE "hashtags"."title" = ? LIMIT ?  [["title", "hash3"], ["LIMIT", 1]]
   (0.0ms)  begin transaction
  SQL (0.3ms)  INSERT INTO "posts" ("title", "content", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["title", "please"], ["content", "please!!!!!"], ["created_at", "2018-03-05 12:43:00.937624"], ["updated_at", "2018-03-05 12:43:00.937624"]]
  SQL (0.1ms)  INSERT INTO "hashtags_posts" ("hashtag_id", "post_id") VALUES (?, ?)  [["hashtag_id", 1], ["post_id", 2]]
   (0.3ms)  rollback transaction
Completed 500 Internal Server Error in 12ms (ActiveRecord: 1.4ms)



ActiveModel::MissingAttributeError (can't write unknown attribute `id`):

app/controllers/posts_controller.rb:36:in `block in create'
app/controllers/posts_controller.rb:35:in `create'
  Rendering /usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout
  Rendering /usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_source.html.erb
  Rendered /usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_source.html.erb (7.4ms)
  Rendering /usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb
  Rendered /usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.0ms)
  Rendering /usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
  Rendered /usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.1ms)
  Rendered /usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (124.9ms)

不知道为什么标题内容,hashtags_attributes是不允许的参数。我正确地将它们设置在白名单中

这是我的代码

posts_controller.rb

  def create
    @post = Post.new(post_params)
    3.times do |x|
      tag = hashtag_params[:hashtags_attributes]["#{x}"]["title"]
      a = Hashtag.find_or_create_by(title: tag)
      @post.hashtags << a
    end

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

  def hashtag_params
      params.require(:post).permit(hashtags_attributes: [:title])
  end

这是我的post.rb

class Post < ApplicationRecord
    has_and_belongs_to_many :hashtags
    accepts_nested_attributes_for :hashtags
end

这是我的hashtag.rb

class Hashtag < ApplicationRecord
  has_and_belongs_to_many :posts
end

终于,我的_form.html.erb

<%= form_for(post) do |f| %>
  <% if post.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(post.errors.count, "error") %> prohibited this post from being saved:</h2>

      <ul>
      <% post.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :title %>
    <%= f.text_field :title %>
  </div>

  <div class="field">
    <%= f.label :content %>
    <%= f.text_area :content %>
  </div>

  <div class="field">
    <%= f.fields_for :hashtags do |h|%>
      <%=h.label :title, "해시태그"%>
      <%=h.text_field :title%>
    <% end %>
  </div>

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

您只需正确指定post_params:

def create
  @post = Post.new(post_params)

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

def post_params
  params.require(:post).permit(:title, :content, hashtags_attributes: [:id, :title])
end

你可以阅读更多here

并且您需要更改迁移

class CreateJoinTableHashtagsPosts < ActiveRecord::Migration[5.0]
  def change
    create_join_table :hashtags, :posts do |t|
      t.index :hashtag_id
      t.index :post_id
    end
  end
end

之后你需要 运行 rake db:rollback && rake db:migrate。 或者您可以使用 rake db:drop && rake db:create && rake db:migrate 从头开始​​重新创建数据库,在这种情况下您将丢失所有现有数据