0

我正在使用表单添加帖子,并且需要将当前用户的 id 与条目参数一起发送。这是我的表单代码:

<%= form_for [@topic, @post] do |f| %>
  <%= render 'shared/error_messages', object: f.object %>
  <div class="field">
        <%= f.hidden_field :user_id, :value => current_user.id %>
    <%= f.hidden_field :topic_id, :value => topic.id %>
        <%= f.text_area :content, placeholder: "yorumunuzu girin..." %>
  </div>
  <%= f.submit "Gönder", class: "btn btn-large btn-primary" %>
<% end %>

和我的 posts_controller :

def new
        @topic= Topic.find_by_id(params[:id])
        @post = @topic.posts.build(params[:post])
    end

    def show
    @post= Post.find(params[:id])
    @topic= @post.topic
  end 

    def create
        @topic= Topic.find_by_id(params[:id])
        @post = @topic.posts.build(params[:post])
        if @post.save
            flash[:success] = "Konu oluşturuldu!"
            redirect_to topic_path(topic)
        else
            render 'static_pages/home'
        end
    end

我使用部分,所以我在 topic_controller.rb 中使用这些代码

  def show      
        @topic = Topic.find(params[:id])
        @posts = @topic.posts.paginate(page: params[:page])
        @post = @topic.posts.build if signed_in?
  end

我嵌套了我的资源:

resources :users
resources :sessions, only: [:new, :create, :destroy]

resources :topics , only: [:show, :create, :destroy] do
resources :posts, only: [:create, :show, :new]
end

. 当我发表评论时,错误日志是:

{"utf8"=>"✓",
 "authenticity_token"=>"y0wzskqK9LfXSPIYW4EmqRii1Tg7bD1CG0kno+gcagQ=",
 "post"=>{"user_id"=>"1",
 "content"=>"yeni yorum"},
 "commit"=>"Gönder",
 "topic_id"=>"3"}

所以它不会发布topic_id. 在主题显示页面中,我想显示主题、属于它的帖子和帖子表单。当用户发表评论时,我希望它重定向到同一页面。所以我redirect_to topic_path(topic)是对还是错?感谢阅读。

编辑 1:我尝试了以下解决方案。我变了

<%= f.hidden_field :user_id, :value => current_user.id %>
<%= f.hidden_field :topic_id, :value => @post.topic.id %>

现在错误代码改变了

 undefined method `posts' for nil:NilClass
{"utf8"=>"✓",
 "authenticity_token"=>"y0wzskqK9LfXSPIYW4EmqRii1Tg7bD1CG0kno+gcagQ=",
 "post"=>{"user_id"=>"1",
 "topic_id"=>"3",
 "content"=>"yorum"},
 "commit"=>"Gönder",
 "topic_id"=>"3"}

我必须编辑我的新动作。我的心被卡住了,但我不会放弃。

4

3 回答 3

1

由于您有嵌套路由(主题下的帖子)并且您使用您构建表单,<%= form_for [@topic, @post] do |f| ... %>您应该topic_id已经可以从您的控制器访问:

params[:topic_id]

(感谢路由)

但是,您不应直接分配topic_id给帖子,而应分配主题实例。

# wrong (security flaw)
@post.topic_id = params[:topic_id]

# correct
@post.topic = Topic.find(params[:topic_id])

这样您就可以对主题进行必要的检查 - 确保它存在,允许用户使用它等。否则用户可以轻松地向您发送他想要的任何值。

[编辑]

出于同样的原因,您不想user_id在表单中发布,因为即使它是隐藏字段,恶意用户也可以手动更改它。而是分配用户在控制器中发布。

@post.user = current_user
于 2012-06-27T09:01:36.550 回答
0

我建议添加一个隐藏的表单字段,在提交后提交值,确保将哈希键值添加到 update_attribute 或 create 方法。

注意:对于隐藏字段,您需要通过添加实际值键来设置值,如下所示:

f.hidden_field, :topic_id, :value => post.topic.id

然后在您的更新或创建函数中,您要添加提交的参数值,如下所示:

n = Comment.new
n.topic_id = params[:form_key][:topic_id].to_i

玩得开心

于 2012-06-27T07:48:50.823 回答
0

这是我的问题的解决方案:

post_controller.rb:

class PostsController < ApplicationController
    before_filter :signed_in_user, only: [:create, :destroy]
  before_filter :correct_user, only: :destroy


    def new
   @topic= Topic.find(params[:topic_id])
   @post = @topic.posts.build
  end

    def create
        @topic= Topic.find(params[:topic_id])
        @post = @topic.posts.build(params[:post])
        @post.user = current_user
        @post.topic_id = @topic.id

        if @post.save
            flash[:success] = "Konu oluşturuldu!"
            redirect_to topic_path(@topic)
        else
            render 'static_pages/home'
        end
    end

  def destroy
    @post.destroy
    redirect_to root_path
  end
  private

    def correct_user
      @post = current_user.posts.find_by_id(params[:id])
      redirect_to root_path if @post.nil?
    end
end

和_post_form.html.erb

  <%= render 'shared/error_messages', object: f.object %>
  <div class="field">


        <%= f.text_area :content, placeholder: "yorumunuzu girin..." %>
  </div>
  <%= f.submit "Gönder", class: "btn btn-large btn-primary" %>
<% end %>

和路由表 routes.rb :

resources :topics , only: [:show, :create, :destroy] do
    resources :posts, only: [:create, :new]
    end

我可以写一篇文章,它会显示在主题页面中。我花了两天时间解决这个问题。感谢所有帮助。

于 2012-06-27T13:21:12.693 回答