我正在使用表单添加帖子,我需要发送当前用户的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
我使用partials所以我在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"}
我必须编辑我的新动作。我的思绪陷入困境,但我不会放弃。
答案 0 :(得分: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
答案 1 :(得分: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
玩得开心
答案 2 :(得分:0)
以下是我的问题的解决方案:
posts_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
我可以写一篇帖子,它会显示在主题页面中。我花了两天时间解决这个问题。谢谢大家的帮助。