0

I am trying to create posts and dynamically generate update forms in the index action. But the forms that are dynamically generated update form are not working. Please find the code below:

posts_controller.rb

class PostsController < ApplicationController
  def index
    @posts = Post.all
  end

  def create
    @post = Post.new(post_params)
    @post.save
  end

  def update
    @post = Post.find(params[:id])
  end

  private

  def post_params
    params.require(:post).permit(:title, :content)
  end
end

index.html.erb

<h4>Posts</h4>
<table class="table table-bordered table-posts">
  <thead>
    <tr>
      <th>Title</th>
      <th>Content</th>
      <th>Actions</th>
    </tr>
  </thead>
  <tbody>
    <% if @posts.present? %>
      <% @posts.each do |post| %>
        <%= render "posts/table_row", post: post %>
      <% end %>
    <% else %>
      <tr class="no-posts-found">
        <td colspan="4" style='text-align: center'>
          No posts found.
        </td>
      </tr>
    <% end %>
  </tbody>
</table>

<h4>Create Post</h4>
<%= form_for Post.new, url: posts_path, method: :post, html: { remote: true }  do |f| %>
  <table class="table table-bordered">
    <tbody>
      <tr>
        <td><%= f.text_field :title, class: "form-control", required: true %></td>
        <td>
          <%= f.text_field :content, class: "form-control", required: true %> 
        </td>
        <td><%= f.submit "Add" %></td>
      </tr>
    </tbody>
  </table>
<% end %>

_table_row.html.erb

<tr class="post-<%= post.id %>">
  <%= form_for post, url: posts_path(post), method: :patch, html: { remote: true }  do |f| %>
    <td><%= f.text_field :title, class: "form-control", required: true %></td>
    <td>
      <%= f.text_field :content, class: "form-control", required: true %> 
    </td>
    <td>
      <%= f.submit "Update" %>
    </td>
  <% end %>
</tr>

create.js.erb

$("table.table-posts").find("tbody").append("<%= j(render 'posts/table_row', post: @post) %>")

update.js.erb

alert("Updated")
webster
  • 3,489
  • 3
  • 32
  • 55
  • You used the `@post` variable for path in `index.html.erb` but you did not define the `@post` variable in `index` action. – demir Aug 09 '19 at 08:18
  • If you are going to create a new post form, you need to add the `@post = Post.new` to index action. – demir Aug 09 '19 at 08:23
  • @demir - Thanks for pointing it out. Between this is not my actual project code. Missed it when I tried to mask project-specific code. – webster Aug 09 '19 at 08:30

2 Answers2

0

You need to update create action for js response.

def create
  ..
  respond_to do |format|
    format.js
  end
end
demir
  • 3,936
  • 2
  • 15
  • 27
  • Create is working perfectly. The issue is with the update action. – webster Aug 09 '19 at 08:57
  • There are many posts. which post will have update form? Are there both create form and update form? – demir Aug 09 '19 at 10:56
  • There are multiple 'update' forms (an 'update' form for each post) and a single create form. Anyways, I was able to fix the issue. Please find my answer below. Thank you! – webster Aug 12 '19 at 06:13
0

A form is not allowed to be a child element of a table, tbody or tr. Attempting to put one there will tend to cause the browser to move the form to it appears after the table (while leaving its contents — table rows, table cells, inputs, etc — behind). Ref - https://stackoverflow.com/a/5967613/3185510

Moving the form inside the <td> tag fixed the issue.

_table_row.html.erb

<tr class="post-<%= post.id %>">
  <td></td>
  <td></td>
  <td>
    <%= form_for post, url: posts_path(post), method: :patch, html: { remote: true }  do |f| %>
      <%= f.text_field :title, class: "form-control", required: true %>
      <%= f.text_field :content, class: "form-control", required: true %>
      <%= f.submit "Update" %>
    <% end %>
  </td>
</tr>
webster
  • 3,489
  • 3
  • 32
  • 55