初始化表单的新对象

时间:2015-06-09 05:18:04

标签: ruby-on-rails

我只是在学铁路,希望有人可以指导我理论问题。

我正在处理的课程作业要求我为部分内容初始化一个新的评论对象,其中包含一个用于提交新评论的表单。如果用户未登录到应用程序,则不会呈现该表单。

据我所知,到目前为止,我们鼓励你在控制器中保留尽可能多的代码,所以我认为这是@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 %>

这是合法的,还是技术不好?

任何建议指出我正确的道德方向,我们表示赞赏!

3 个答案:

答案 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?