Ruby on rails 初始化窗体的新对象
我正在学习rails,希望有人能在理论问题上指导我 我正在处理的课程作业要求我为一个部分初始化一个新的注释对象,该部分包含一个用于提交新注释的表单。如果用户未登录到应用程序,则不会呈现表单 据我所知,我们鼓励您在控制器中保留尽可能多的代码,因此我认为这是初始化@comment=@post.comments.new的最佳位置 posts_controller.rb中的代码段:Ruby on rails 初始化窗体的新对象,ruby-on-rails,Ruby On Rails,我正在学习rails,希望有人能在理论问题上指导我 我正在处理的课程作业要求我为一个部分初始化一个新的注释对象,该部分包含一个用于提交新注释的表单。如果用户未登录到应用程序,则不会呈现表单 据我所知,我们鼓励您在控制器中保留尽可能多的代码,因此我认为这是初始化@comment=@post.comments.new的最佳位置 posts_controller.rb中的代码段: def show @topic = Topic.find(params[:topic_id]) @po
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 %>
<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 %>
添加注释:
下面是调用部分post/show.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 %>
<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 %>
这是合法的,还是拙劣的技术
任何能给我指出正确道德方向的建议都将不胜感激 这看起来确实可行,但如果没有看到您的政策,我们无法确定。假设您使用的是Desive,您还可以尝试以下方法来简单地检查当前用户是否在场
<% 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 %>
是的,这在目前是可行的,但是,如果您以后更改了新评论的策略,该怎么办?然后,你必须找到你使用过的所有地方并修复它们。坚持这样做可能会更好,因为可以在一个地方进行更改,坚持干燥 我的代码确实有效。我只是想知道视图是否是实例化对象的合适位置
我确实在这里找到了答案:我认为主要问题在于控制器中的
authorize@comment
行。这条线首先给你带来了问题,所以让我们考虑改变它。
因为这是posts控制器,所以您应该在那里授权post对象,而不是comment对象。这样,您可以在控制器中保留@comment
的创建。无论如何,它更符合Rails惯例
在视图中使用
if-policy(Comment.new).create?
是正确的,不过通过此更改,您现在也可以在posts/show中执行if-policy(@Comment).create?
创建注释对象..对吗?这是正确的,但仅当用户登录时。我的意思是在posts.show.中建议的编码中包含authorize@comment,因此在视图中,如果当前用户正确,您可以检查条件。我还刚刚验证了应该使用@comment=comment.new在视图中初始化新注释。我的基本问题是,这是一种可接受的编码方式,还是应该将初始化保存在控制器中。policy(Comment.new)。create?
此语句的作用是什么?