【问题标题】:accepts_nested_attributes_for with hidden_field接受_nested_attributes_for 和 hidden_​​field
【发布时间】:2014-02-16 04:47:38
【问题描述】:

整天都在寻找 stackoverflow 的答案。我有一个创建新主题的表格。第一篇文章也应该使用该主题创建。一切都很好,除了 user_id 没有保存到帖子中。

后模型

class Post < ActiveRecord::Base
  belongs_to :topic
  belongs_to :user
end

主题模型

class Topic < ActiveRecord::Base
  belongs_to :forum
  belongs_to :user  
  has_many :posts 
  accepts_nested_attributes_for :posts
end

后控制器

class PostsController < ApplicationController

  def new
    @post = Post.new
  end

  def create
    @post = Post.new(post_params)
    if @post.save
      redirect_to topic_path(@post.topic_id)
    else
      render 'new'
    end
  end

  private

  def post_params
    params.require(:post).permit(:content, :topic_id, :topic_name, :user_id)
  end

结束

主题控制器

class TopicsController < ApplicationController

  def new
    @topic = Topic.new
    @topic.posts.build
  end

  def create
    @topic = Topic.new(topic_params)
    if @topic.save
      redirect_to @topic
    else
      render 'new'
    end
  end

  private

  def topic_params
    params.require(:topic).permit(
      :topic_name, 
      :forum_id, 
      :user_id,  
      posts_attributes: [:id, :content, :topic_id, :topic_name, :user_id ] )
  end
end

新/主题视图

<%= form_for(@topic) do |f| %> 
   <%= f.hidden_field :forum_id, :value => params[:forum_id] %>
   <%= f.hidden_field :user_id, :value => current_user.id %>
   <%= f.label :topic_name %>
   <%= f.text_field :topic_name %>
   <%= f.fields_for :posts do |p| %>
     <%= p.label :content %>
     <%= p.text_area :content %>
   <% end %>

   <%= f.submit "Post Topic", class: "btn btn-large btn-success" %>
<% end %>

我不完全确定为什么没有将 user_id 传递给帖子。希望比我聪明的人可以帮助我学习该做什么:)

更新

我将主题控制器中的强参数更改为这个。

def topic_params
  params.require(:topic).permit(
  :topic_name, 
  :forum_id, 
posts_attributes: [:content, :topic_id, :id, '_destroy' ] ).merge(:user_id => current_user.id, posts_attributes: [:user_id => current_user.id]) 
    end

现在 user_id 正在工作,但没有像 :content 这样的 posts_attributes 被保存。我玩这个很开心..

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4


    【解决方案1】:

    注意浏览器中生成的表单属性,所有post的嵌套属性都有topic[post_attributes]这样的前缀,尝试将表单更改为:

    <%= form_for(@topic) do |f| %> 
       <%= f.hidden_field :forum_id, :value => params[:forum_id] %>
       <%= f.label :topic_name %>
       <%= f.text_field :topic_name %>
       <%= f.fields_for :posts do |p| %>
         <%= p.hidden_field :user_id, :value => current_user.id %>
         <%= p.label :content %>
         <%= p.text_area :content %>
       <% end %>
    
       <%= f.submit "Post Topic", class: "btn btn-large btn-success" %>
    <% end %>
    

    【讨论】:

    • 我在它仍然不包含 user_id 之前试过这个。
    【解决方案2】:

    简短的回答,user_id 不在posts_attributes 中,因为那里唯一的属性是content,这意味着允许其他属性如topic_idtopic_name 是没有用的。

    既然我们已经清除了这一点,您不应该使用表单输入作为任何模型的创建者的值,因为任何人都可以很容易地篡改表单并将值设置为其他任何值,例如其他用户的 id。或者,您应该在控制器中设置user_id 值,在您的情况下是TopicsController。代码如下:

    def create
      _params = topic_params.deep_merge(user: current_user, posts_attributes: {user: current_user})
      @topic = Topic.new(_params)
      if @topic.save
        redirect_to @topic
      else
        render 'new'
      end
    end
    

    并从表单中删除 user_id 隐藏字段。

    更新:您上次的代码更新包含错误;它应该是.merge(:user_id =&gt; current_user.id, posts_attributes: {:user_id =&gt; current_user.id})。您在 :user_id =&gt; current_user.id 周围使用了方括号,而不是大括号。

    【讨论】:

    • 我没有意识到我不应该使用 hidden_​​field。我使用了你的代码并得到了错误未定义的方法 `with_indiffer_access' for #<0x5ef0c80>
    猜你喜欢
    • 1970-01-01
    • 2011-03-04
    • 1970-01-01
    • 1970-01-01
    • 2011-12-05
    • 2013-12-24
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    相关资源
    最近更新 更多