Initializing a new object for the form

I am just studying rails and hope someone can guide me on a theoretical question.

The assignment of the course I'm working on requires me to initialize a new comment object for a partial, which includes a form to submit a new comment. The form should not be displayed if the user is not signed in to the application.

From what I know so far, you are encouraged to keep as much code as possible in the controller, so I figured this is the best place to initialize @comment = @ post.comments.new.

An excerpt from 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

      

And here are the partial comments of /_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 %>

      

And here is the form that calls the partial entry /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 %>

      

The problem is that if the user is not logged in for the application, the authorization for @comment does not work in the controller and prevents posts / show.html.erb from being displayed.

Maybe I could do something like this in 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 %>

      

Is this legal or is it a bad method?

Any advice pointing me in the right moral direction is greatly appreciated!

+3


source to share


3 answers


I think the main problem is with the line authorize @comment

in the controller. First of all, this led to problems, so we will consider the possibility of changing them.

Since it is a post controller, then you must allow the post object there, not the comment object. This way, you can leave the creation @comment

in the controller. Either way, this is consistent with Rails conventions.



The usage if policy(Comment.new).create?

in the view is correct, although with this change you can also do if policy(@comment).create?

.

0


source


It looks like it will work, but without seeing your policy, we cannot be sure. You can also try the following to just check if the current user is present if you are using it.



<% 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 %>

      

0


source


Yes, it will work for now, but what if you later change the policy for new comments? You would then need to hunt down all the places where you used <% if current_user.present? %> and fix them. It's probably best to stick with the <% if (Comment.new) .create policy? %>, so changes can be made in one place while sticking to DRY.

My code works. I was just wondering if the view was the right place to create objects.

I found my answer here: Okay, to create an object in a view?

0


source







All Articles