Rails - 在视图中提交表单后加载AJAX

时间:2017-08-16 16:15:48

标签: javascript ruby-on-rails ruby ajax

在通过AJAX提交视图后,我无法使用帖子加载/填充视图。表单本身正在启动并将帖子插入数据库。为了更清楚,我需要在提交后使用JQuery slideDown在帖子下面的容器中加载帖子。我有一个普通的帖子/共享帖子/评论帖子,索引动作中的部分渲染。

index.html.erb

<div class="col-md-5">
      <div class="posts-feed-bg">
        <div id="post-index-form">
          <%= render 'posts/form' %>
        </div>
        <div class="post-textarea-bottom-border"></div>
        <div class="post-feed-container" id="posts-items">
          <% @posts.each do |post| %>
              <%= render partial: "posts/#{post.post_type}", locals: {post: post} %>
          <% end %>
        </div>
      </div>
    </div>

create.js.erb

<% if @post.save
      @post = Post.new
%>
    $('#post-index-form').html('<%= escape_javascript(render 'posts/form') %>');
    $('#post-text-area').val('');
    $('#post-items').html('<%= escape_javascript(render 'posts/post') %>');
    $('#post-items').slideDown(350);
    <% end %>

_post.html.erb

  <div class="post-container">
    <%= post.user.username %>
    <%= link_to post.title, post %>
    <%= post.body %>
    </div>

posts_controller.rb

def index
        following_ids = current_user.following_users.map(&:id)
        following_ids << current_user.id
        @posts = Post.where(user_id: following_ids).order('created_at DESC').paginate(page: params[:page])
        @users = User.same_background_focus_as(current_user).paginate :page => params[:page], :per_page => 5
        @post = Post.new
      end

 def create
    @post = current_user.posts.build(post_params)

    respond_to do |format|
      if @post.save
        format.html { redirect_to @post, notice: 'Post was successfully created.' }
        format.json { render :show, status: :created, location: @post }
        format.js
      else
        format.html { render :new }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

_form.html.erb

<div class="container">
    <%= simple_form_for(@post, id: '', multipart: true, remote: true) do |f| %>
        <%= f.error_notification %>
        <div class="row">
          <div class="col-6 emoji-picker-container post-textarea">
            <%= f.input :body_text, class: 'form-control', label: false, id: 'post-text-area' %>
          </div>
        </div>
        <div class="row">
          <div class="col-md-5">
            <%= f.button :submit, class: 'btn btn-outline-success' %>
          </div>
        </div>
    <% end %>
</div>

提交表单后的服务器日志

Started POST "/posts" for 127.0.0.1 at 2017-08-16 13:25:25 -0400
Processing by PostsController#create as JS
  Parameters: {"utf8"=>"✓", "post"=>{"body_text"=>"AJAX"}, "commit"=>"Create Post"}
  User Load (1.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 4], ["LIMIT", 1]]
   (1.0ms)  BEGIN
  SQL (174.6ms)  INSERT INTO "posts" ("body_text", "user_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["body_text", "AJAX"], ["user_id", 4], ["created_at", "2017-08-16 17:25:26.201583"], ["updated_at", "2017-08-16 17:25:26.201583"]]
   (0.5ms)  COMMIT
  Rendering posts/create.js.erb
   (1.0ms)  BEGIN
   (0.0ms)  COMMIT
  Rendered posts/_form.html.erb (8.0ms) [cache miss]
  Rendered posts/_post.html.erb (1273.9ms)
  Rendered posts/create.js.erb (1366.9ms)
Completed 500 Internal Server Error in 2282ms (ActiveRecord: 178.1ms)



ActionView::Template::Error (undefined local variable or method `post' for #<#<Class:0x18937128>:0x1a9f6688>
Did you mean?  @post
               post_url):
    2:   <div class="media" style="padding-bottom: 2em;">
    3:     <img class="d-flex align-self-start mr-3 purple-rounded rounded" src="http://via.placeholder.com/60x60">
    4:     <div class="media-body post-user-name">
    5:       <h5><%= fa_icon 'user' %> <%= post.user.user_full_name %><%= link_to 'Delete', post_path(post), remote: true, method: :delete, data: {confirm: "You sure?"} if current_user == post.user %> </h5>
    6:       <p><%= post.body_text %> </p>
    7:     </div>
    8:   </div>

app/views/posts/_post.html.erb:5:in `_app_views_posts__post_html_erb__960034244_222460104'
app/views/posts/create.js.erb:9:in `_app_views_posts_create_js_erb__1048995870_223328388'

进行更改后出现新错误

ActionView::Template::Error (undefined method `user_full_name' for nil:NilClass):
    2:   <div class="media" style="padding-bottom: 2em;">
    3:     <img class="d-flex align-self-start mr-3 purple-rounded rounded" src="http://via.placeholder.com/60x60">
    4:     <div class="media-body post-user-name">
    5:       <h5><%= fa_icon 'user' %> <%= post.user.user_full_name %><%= link_to 'Delete', post_path(post), remote: true, method: :delete, data: {confirm: "You sure?"} if current_user == post.user %> </h5>
    6:       <p><%= post.body_text %> </p>
    7:     </div>
    8:   </div>

app/views/posts/_post.html.erb:5:in `_app_views_posts__post_html_erb__960034244_199162944'
app/views/posts/create.js.erb:9:in `_app_views_posts_create_js_erb__1048995870_199612656'

部分视图转换器的方法  post.rb

def post_type
    if post_id? && body_text?
      "quote_share"
    elsif post_id?
      "share"
    else
      "post"
    end
  end

1 个答案:

答案 0 :(得分:0)

问题是您错误地引用了id 。您已将divid定义为posts-items,但在create.js.erb中您使用的post-items不正确,因此 JS 无法找到post-items选择器,这是问题的原因。将其更改为posts-items可以解决您的问题。

#create.js.erb
<% if @post.save
  @post = Post.new
%>
  $('#post-index-form').html('<%= escape_javascript(render 'posts/form') %>');
  $('#post-text-area').val('');
  $('#posts-items').html('<%= escape_javascript(render 'posts/post') %>');
  $('#posts-items').slideDown(350);
<% end %>

此外,这部分代码。

<% if @post.save
  @post = Post.new
%>

看起来很奇怪。除非有用,否则我在create.js.erb中看不到包含它的任何原因。所以删除它

#create.js.erb
$('#post-index-form').html('<%= escape_javascript(render 'posts/form') %>');
$('#post-text-area').val('');
$('#posts-items').html('<%= escape_javascript(render 'posts/post') %>');
$('#posts-items').slideDown(350);

<强>更新

  

ActionView :: Template :: Error(未定义的局部变量或方法`post&#39;   for#&lt;#&lt; Class:0x18937128&gt;:0x1a9f6688&gt;

在这种情况下,Rails无法找到post中定义的_post.html.erb变量。将其作为局部变量发送到局部变量中。最终的create.js.erb应该是这样的

#create.js.erb
$('#post-index-form').html('<%= escape_javascript(render 'posts/form') %>');
$('#post-text-area').val('');
$('#posts-items').html('<%= escape_javascript(render 'posts/post', post: @post) %>');
$('#posts-items').slideDown(350);

另外,将@post更改为Post.new中的form,以便它与@post操作中的create发生冲突,并始终创建表单对于新实例

<%= simple_form_for(Post.new, id: '', multipart: true, remote: true) do |f| %>
  

ActionView :: Template :: Error(未定义的方法`user_full_name&#39; for   零:NilClass)

此错误是因为该特定帖子没有关联的用户,因此该行错误<%= post.user.user_full_name %>要快速解决错误,请使用try方法

<%= post.try(:user).user_full_name %>