为什么将参数传递给 link_to 不起作用?

Why is this passing of params into link_to not working?

在尝试了最初评论中提到的几件事后仍然无法正常工作 - 我在下面进行了修改以反映这些努力/澄清一些事情。

问题摘要:我无法创建新的 Post(答案),其中 Post 的 parent_id 等于相关问题的 Post 的 ID .用户从问题 Post 的 posts#show 页面开始,然后单击 "Answer"。我原以为下面的代码会将问题 Post 的 ID 传递给答案 Posts' parent_id。但事实并非如此。它 returns parent_id = nil

我有一个 Posts 模型。 Post 的 post_type_id 为 1(问题)或 2(答案)。

所有 post_type_id = 2 的 Post 都有一个 parent_id 指向正在回答的问题的 ID。

在帖子#show 我有:

<% case post_type %> 
  <% when 1 %>
<%= link_to 'Answer', new_post_path(:parent_id => @post.id) %>
  <% else %>
<% end %>

当我点击它时,它会将我带到 new_post 页面,url 是: //localhost:3000/posts/new?parent_id=6

(这个例子中的问题有 id = 6,所以我认为这看起来是正确的。)

在我的 Posts 控制器中,我有:

  def new
    @post = Post.new
  end

  def show
  end

  def create
    @post = Post.new(post_params)
    @post.user_id = current_user.id
    @post.parent_id = params[:parent_id]

    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(:user_id, :post_type_id, :title, :content, :accepted_answer_id, :parent_id, :score, :answer_count, :favorite_count)
  end

我的路线是:

          posts GET    /posts(.:format)                   posts#index
                POST   /posts(.:format)                   posts#create
       new_post GET    /posts/new(.:format)               posts#new
      edit_post GET    /posts/:id/edit(.:format)          posts#edit
           post GET    /posts/:id(.:format)               posts#show
                PATCH  /posts/:id(.:format)               posts#update
                PUT    /posts/:id(.:format)               posts#update
                DELETE /posts/:id(.:format)               posts#destroy

在new.html.erb我有:

<h3>New Post</h3>
<%= render 'form' %>
<%= link_to 'Back', posts_path %>

而_form.html.erb是:

<%= simple_form_for(@post) do |f| %>
<%= f.error_notification %>

<div class="form-inputs">
<%- f.association :user %>
<%= f.input :post_type_id, collection: post_types, label: 'What do you want to do?' %>
<%= f.input :title %>
<%= f.input :content %>
<%- f.input :accepted_answer_id %>
<%- f.input :parent_id %>
<%- f.input :score %>
<%- f.input :answer_count %>
<%- f.input :favorite_count %>
</div>

<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>

我非常感谢有关如何使它正常工作的任何建议。

谢谢!

好的,您的用户点击答案,然后将问题 ID 作为 ROOT 参数转发 (params[:parent_id])

现在,您想告诉您的新操作,您正在构建的 post 是问题的答案,因此您应该在此处使用参数

controllers/posts_controller.rb

def new
  @post = Post.new
  @post.parent_id = params[:parent_id] if params[:parent_id]

然后在你的表单中,你可以添加一个隐藏字段(用户不关心id)。我相信如果字段 .parent_id 没有设置,它会留下一个空白值并且没关系

views/posts/_form.html.erb

<%= f.hidden_field :parent_id %>

然后当您POST您的新答案时,将发送:parent_id,您无需担心

controllers/posts_controller.rb

def create
    @post = Post.new(post_params)
    @post.user_id = current_user.id
    # No need for the below line, :parent_id is already in post_params
    # @post.parent_id = params[:parent_id]

    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(..., :parent_id, ...)
  end

编辑:在评论中回答您的问题

为什么@post.parent_id = params[:parent_id]属于#new

通过这一行,您实际上设置了您正在为#new 操作准备的 "template @post object" 的 :parent_id 内存变量。现在,当您呈现视图时,默认情况下每个表单助手都会加载内存中的值(如果存在)。当您执行 f.input :content 时,form_builder 将生成 HTML 标记,但也会在内存中查找 @post.content。因为模型是空白生成的,所以没有值,所以它会显示一个空字段。所以当你调用 f.hidden_field :parent_id 时,它实际上会找到变量(感谢我们刚刚添加的代码)并使用它。

<%- 而不是 <%=

我个人从不使用 <%-,我不得不 google 它,并找到了 this question<%- 只会避免换行,所以它也可以工作

为什么要隐藏字段?

这只是用户体验的问题。隐藏字段将写入 HTML,但会将其隐藏给用户。用户根本不在乎你的 :parent_id。您正在使用 ActiveRecord,所以 ID 看起来非常好,但是如果您尝试使用其他数据库系统,您的 ID 可能看起来像 0bef0600008de。而且您的用户绝对不关心他正在为问题 0bef0600008de.

添加答案

不过 h 可能对此感兴趣 :

_form.html.erb

<% if @post.parent_id %> <!-- if variable parent_id exists <=> we are writing an answer -->
  <h2>You are writing an answer for the question <%= Post.find(@post.parent_id).title %></h2>
<% end %>