我只是在学铁路,希望有人可以指导我理论问题。
我正在处理的课程作业要求我为部分内容初始化一个新的评论对象,其中包含一个用于提交新评论的表单。如果用户未登录到应用程序,则不会呈现该表单。
据我所知,到目前为止,我们鼓励你在控制器中保留尽可能多的代码,所以我认为这是@comment = @ post.comments.new初始化的最佳位置。
来自posts_controller.rb的片段:
def show
@topic = Topic.find(params[:topic_id])
@post = Post.find(params[:id])
@comment = @post.comments.new
authorize @comment
@comments = @post.comments.all
end
这是部分评论/ _form.html.erb:
<h3>Add a comment:</h3>
<%= form_for [topic, post, comment], html: {class: "form-inline"} do |f| %>
<%= f.label "Body" %>
<%= text_field(:comment, :body) %>
<%= f.submit "Create Comment" %>
<% end %>
这是调用部分帖子/ show.html.erb的表单:
<h1><%= markdown_to_html @post.title %></h1>
<div>
<%= image_tag(@post.image.small.url) if @post.image? %>
</div>
<div class="row">
<div class="col-md-8">
<small>
<%= image_tag(@post.user.avatar.tiny.url) if @post.user.avatar? %>
submitted <%= time_ago_in_words(@post.created_at) %> ago by
<%= @post.user.name %>
</small>
<p><%= markdown_to_html @post.body %></p>
</div>
<div class="col-md-4">
<% if policy(@post).edit? %>
<%= link_to "Edit", edit_topic_post_path(@topic, @post), class: 'btn btn-success' %>
<% end %>
</div>
</div>
<div class="row">
<div class="col-md-1">
<h1>Comments</h1>
</div>
</div>
<%= render partial: "comments/comments", collection: @comments, as: :comment %>
<% if policy(Comment.new).create? %>
<div class="row">
<div class="col-md-12">
<%= render partial: "comments/form", locals: { topic: @topic, post: @post, comment: @comment } %>
</div>
</div>
<% end %>
问题是,如果用户未登录到应用程序,则@comment的授权在控制器中失败,并阻止发布posts / show.html.erb。
也许我可以在posts / show.html.erb中做这样的事情?:
<% if policy(Comment.new).create? %>
<% @comment = Comment.new %>
<div class="row">
<div class="col-md-12">
<%= render partial: "comments/form", locals: { topic: @topic, post: @post, comment: @comment } %>
</div>
</div>
<% end %>
这是合法的,还是技术不好?
任何建议指出我正确的道德方向,我们表示赞赏!
答案 0 :(得分:0)
这看起来确实有效,但如果没有看到你的政策,我们就无法确定。假设您正在使用设计,您还可以尝试以下操作来简单地检查是否存在当前用户。
<% if current_user.present? %>
<% @comment = Comment.new %>
<div class="row">
<div class="col-md-12">
<%= render partial: "comments/form", locals: { topic: @topic, post: @post, comment: @comment } %>
</div>
</div>
<% end %>
答案 1 :(得分:0)
是的,这暂时可行,但是,如果您之后更改了新评论的政策,该怎么办?然后你必须追捕你使用的所有地方&lt;%if current_user.present? %GT;并修复它们。最好坚持使用&lt;%if policy(Comment.new).create? %GT;所以可以在一个地方做出改变,坚持干。
我的代码确实有用。我只是想知道视图是否是实例化对象的适当位置。
我确实在这里找到了答案:Ok to instantiate an object in the View?
答案 2 :(得分:0)
我认为主要问题在于控制器中的authorize @comment
行。这条线首先引起了你的问题,所以我们考虑改变它。
由于这是posts控制器,那么你应该在那里授权一个post对象,而不是一个comment对象。这样您就可以在控制器中保留@comment
的创建。无论如何,它更符合Rails惯例。
在视图中使用if policy(Comment.new).create?
是正确的,但是通过此更改,您现在也可以执行if policy(@comment).create?
。