简体   繁体   English

Rails 5 AJAX拒绝渲染局部

[英]Rails 5 AJAX refusing to render partial

I created an AJAX function that allows you to click to refresh posts at the top of the stack. 我创建了一个AJAX函数,使您可以单击以刷新堆栈顶部的帖子。 Unfortunately, the ajax function is receiving the wrong parameters and returning server error 500. I am simply trying to load the latest posts available (most recent) I can't catch where the error is coming from. 不幸的是,ajax函数接收到错误的参数并返回服务器错误500。我只是在尝试加载可用的最新帖子(最新),我无法捕捉到错误的来源。 What do I need to do to get the newest posts to load on the stack using AJAX GET in index.html.erb? 使用index.html.erb中的AJAX GET,如何做才能将最新的帖子加载到堆栈中?

posts_controller.rb posts_controller.rb

class PostsController < ApplicationController

before_action :set_post, only: %[show edit update destroy share like]
before_action :authenticate_user!

def index
  following_ids = current_user.following_users.pluck(:id)
  following_ids << current_user.id
  @posts = Post.where(user_id: following_ids).order('created_at DESC').page(params[:page])
  @post = Post.new
end

def load_more
  following_ids = current_user.following_users.pluck(:id)
  following_ids << current_user.id
  @posts = Post.where(user_id: params[:following_ids]).order('created_at DESC').limit(20)
  respond_to do |format|
    format.html
    format.js
  end
end

index.html.erb index.html.erb

<div class="col-md-5">
  <div class="post-feed-bg">
    <div id="post-index-form" class="post-form-bottom-padding">
      <%= render 'posts/form' %>
    </div>

    <!---LOAD MORE POSTS BUTTON-->
      <%= link_to load_more_path(@posts), class: 'bttn-material-circle bttn-danger bttn-md load-more-posts', :remote => true do %>
        <i class="fas fa-sync"></i>
      <% end %>

    <div class="post-textarea-bottom-border"></div>
    <div class="text-center">
      <%= image_tag 'post/loading.gif', style: 'display: none;', class: 'loading-gif' %>
    </div>
    <div class="post-feed-container" id="container_posts">
      <% if @posts.present? %>
        <%= render partial: "posts/posts", locals: {posts: @posts} %>
       <% end %>
    </div>
  </div>
</div>

_posts.html.erb _posts.html.erb

<% @posts.each do |post| %>
  <div class="post-container" data-id="<%= post.id %>">
    <div class="media" style="padding-bottom: 2em;">
      <%= user_avatar_post(post.user) %>
      <div class="media-body post-user-name">
        <h5><i class="fas fa-user"></i> <%= link_to post.user.user_full_name, user_path(post.user) %></h5>
        <p><%= linkify_hashtags(post.body_text) %> </p>
      </div>
    </div>
    <div class="post-container-charm-bar">
      <ul>
        <li class="votes" id="#post_<%= post.id %>">
          <%= link_to like_post_path(post), style: 'text-decoration: none', class: 'like-btn', method: :put, remote: true do %>
            <p id="thumb-id" class="thumbs-up" style="cursor: pointer;">b</p>
          <% end %>
        </li>
        <li><strong class="likes-count"><%= number_with_delimiter(post.get_likes.size) %></strong></li>
        <li><%= link_to '#', data: {toggle: "modal", target: "#commentmodal"} do %>
            <%= link_to post_path(post, anchor: 'comments') do %>
              <i class="far fa-comments post-charm-bar-icon-color fa-2x"></i>
            <% end %>
          <% end %>
        </li>
        <li><strong><%= post.comment_threads.size %></strong></li>
        <li>
          <%= link_to({controller: 'posts', action: 'share', id: post.id}, method: :post, remote: true, style: 'text-decoration: none;')  do %>
            <i class="far fa-share-square fa-2x "></i>
          <% end %>
        </li>
        <li>
          <%= link_to post, style: 'text-decoration: none;' do %>
            <i class="fas fa-eye fa-2x"></i>
          <% end %>
        </li>
        <li>
          <%= link_to edit_post_path(post), style: 'text-decoration: none;' do %>
            <i class="fas fa-pencil-alt fa-2x post-charm-bar-icon-color"></i>
          <% end %>
        </li>
        <li>
          <% if current_user == post.user %>
            <%= link_to post_path(post), style: 'text-decoration: none;', method: :delete, remote: true do %>
              <i class="fas fa-trash-alt fa-2x"></i>
            <% end %>
          <% end %>
        </li>
      </ul>
    </div>

    <div class="container-fluid">
      <div class="row">
        <div class="col-md-12 post-image">
          <% if post.photo.present? %>
            <%= image_tag post.photo.feed_preview, class: 'd-flex align-self-start mr-3 img-fluid rounded', lazy: true %>
          <% else %>
          <% end %>
        </div>
      </div>
    </div>
  </div>
<% end %>


<script type="text/javascript">
    $(document).ready(function () {
        $("img").lazyload({
            effect: "fadeIn",
            skip_invisible: true,
            threshold: 500
        });
    });
</script>

index.js.erb index.js.erb的

// Load new records
$("#container_posts").prepend("<%= escape_javascript(render(@posts)) %>").hide().fadeIn(1000);


//Append new data
$("<%= j render partial: "posts/#{@post.post_type}", locals: {post: @post } %>").appendTo($("#container_posts"));

//Update pagination link
<% if @posts.last_page? %>
$('.pagination').html("All done");
<% else %>
$('.pagination').html("<%= j link_to_next_page(@posts, 'Next Page', :remote => true) %> ");

routes.rb 的routes.rb

 resources :posts, on: :collection do
    member do
    ......
    end
  end
  get "/load_more", to: "posts#load_more", as: 'load_more'

load_more_posts.js load_more_posts.js

$(document).on('turbolinks:load', function () {
    $('a.load-more-posts').click(function (e) {
        // prevent the default click action
        e.preventDefault();

        // hide more load more link
        $('.load-more-posts').hide();

        // show loading gif
        $('.loading-gif').show();
        // get the last id and save it in a variable 'last-id'
        var last_id = $('.post-container').last().attr('data-id');

        // make an ajax call passing along our last career insight id
        $.ajax({
            // make a get request to the server
            type: "GET",
            // get the url from the href attribute of our link
            url: "/posts",
            // send the last id to our rails app
            data: {
              id: last_id,
              user_profile: "", // maybe nil in certain cases
              _: ""
            },
            // the response will be a script
            dataType: "script",
            success: function (data, textStatus, jqXHR) {
                if (jqXHR.status == "204") {
                    $('.loading-gif').hide();
                    $('.load-more-posts').show();
                }

                $('.loading-gif').hide();
                $('.load-more-posts').show();
            },
            error: function (jqXHR, exception) {
            }
        })
    });
});

post parameters 发布参数

=> #<Post id: 59, body_text: "Fix this!", photo: nil, user_id:
 2, created_at: "2018-11-02 19:13:09", updated_at: "2018-11-02 19:13:09", post_id: nil, post_id: nil, post_counter: 0, cached_votes_total: 0, cached_votes_score: 0, cached_votes_up: 0, cached_votes_do
wn: 0, cached_weighted_score: 0, cached_weighted_total: 0, cached_weighted_avera
ge: 0.0, hash_id: "DQxad5rRVvfb">

server stacktrace 服务器堆栈跟踪

Started GET "/load_more.%23%3CPost::ActiveRecord_Relation:0x0000000016f89718%3E" for 127.0.0.1 at 2018-11-03 00:32:58 -0400
Started GET "/posts?id=41&user_profile=&_=1541219410513" for 127.0.0.1 at 2018-11-03 00:32:58 -0400
Processing by PostsController#load_more as 
Processing by PostsController#index as JS
  Parameters: {"id"=>"41", "user_profile"=>"", "_"=>"1541219410513", "on"=>:collection}
  User Load (3.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 5], ["LIMIT", 1]]
  User Load (2.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 5], ["LIMIT", 1]]
DEPRECATION WARNING: Setting custom parent classes is deprecated and will be removed in future versions. (called from parent_class_name at C:/Ruby24-x64/lib/ruby/gems/2.4.0/bundler/gems/acts_as_follower-c5ac7b9601c4/lib/acts_as_follower/follower_lib.rb:10)
DEPRECATION WARNING: Setting custom parent classes is deprecated and will be removed in future versions. (called from parent_class_name at C:/Ruby24-x64/lib/ruby/gems/2.4.0/bundler/gems/acts_as_follower-c5ac7b9601c4/lib/acts_as_follower/follower_lib.rb:10)
   (2.0ms)  SELECT "users"."id" FROM "users" INNER JOIN "follows" ON "follows"."followable_id" = "users"."id" AND "follows"."followable_type" = $1 WHERE "follows"."blocked" = $2 AND "follows"."follower_id" = $3 AND "follows"."follower_type" = $4 AND "follows"."followable_type" = $5  [["followable_type", "User"], ["blocked", false], ["follower_id", 5], ["follower_type", "User"], ["followable_type", "User"]]
   (58.0ms)  SELECT "users"."id" FROM "users" INNER JOIN "follows" ON "follows"."followable_id" = "users"."id" AND "follows"."followable_type" = $1 WHERE "follows"."blocked" = $2 AND "follows"."follower_id" = $3 AND "follows"."follower_type" = $4 AND "follows"."followable_type" = $5  [["followable_type", "User"], ["blocked", false], ["follower_id", 5], ["follower_type", "User"], ["followable_type", "User"]]
Completed 406 Not Acceptable in 127ms (ActiveRecord: 5.0ms)



ActionController::UnknownFormat (ActionController::UnknownFormat):

SERVER Stacktrace Update 2 服务器Stacktrace更新2

Rendered collection of posts/_post.html.erb [25 times] (3464.5ms)
  Rendered posts/_post.html.erb (2329.4ms)
  Rendered posts/index.js.erb (10273.4ms)
Completed 500 Internal Server Error in 109620ms (ActiveRecord: 24197.5ms)



ActionView::Template::Error (undefined method `user_profile' for nil:NilClass):
    1: <div class="post-container" id="post_<%= post.id %>" data-id="<%= post.hash_id %>">
    2:   <div class="media" style="padding-bottom: 2em;">
    3:     <%= user_avatar_post(post.user) %>
    4:     <div class="media-body post-user-name">
    5:       <h5><i class="fas fa-user"></i> <%= link_to  full_name(post.user), user_path(post.user) %></h5>
    6:       <p><%= linkify_hashtags(post.body_text) %> </p>

app/helpers/posts_helper.rb:3:in `user_avatar_post'
app/views/posts/_post.html.erb:3:in `_app_views_posts__post_html_erb__891594994_136890360'
app/views/posts/index.js.erb:6:in `_app_views_posts_index_js_erb__704681650_227473700'
Processing by ExceptionHandler::ExceptionsController#show as JS
  Parameters: {"id"=>"41", "_"=>"1541262709872", "on"=>:collection}
Error during failsafe response: Could not render layout: undefined method `[]' for nil:NilClass
  C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/actionview-5.2.0/lib/action_view/layouts.rb:418:in `rescue in _default_layout'
  C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/actionview-5.2.0/lib/action_view/layouts.rb:415:in `_default_layout'
  C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/actionview-5.2.0/lib/action_view/layouts.rb:392:in `block in _layout_for_option'
  C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/actionview-5.2.0/lib/action_view/renderer/template_renderer.rb:96:in `resolve_layout'

_post.html.erb partial is not rendering with user and bypassing helper methods in posts_helper.rb _post.html.erb部分不与用户一起呈现,并绕过posts_helper.rb中的帮助器方法

posts_helper.rb posts_helper.rb

module PostsHelper
  def user_avatar_post(current_user)
    if current_user.user_profile.avatar.feed_thumb.url.nil?
      inline_svg 'user_dashboard/add-user-avatar.svg', size: '12% * 12%', class: 'd-flex align-self-start mr-3 purple-rounded rounded'
    else
      image_tag current_user.user_profile.avatar.feed_thumb.url, class: 'd-flex align-self-start mr-3 img-thumbnail rounded'
    end
  end

   def full_name(user)
     user.first_name + ' ' + user.last_name
   end
end

Updated Post Controller 更新后的控制器

def load_more
  if params[:last_post_id]
    following_ids = current_user.following_users.pluck(:id)
    following_ids << current_user.id
    @posts = Post.where(user_id: params[:following_ids]).where('id < ?', params[:last_post_id]).order('created_at DESC').limit(20)
  else
    head :no_content
  end
  respond_to do |format|
    format.html
    format.js
  end
end

rotute.erb rotute.erb

get "/load_more/:last_post_id", to: "posts#load_more", as: 'load_more'

index.html.erb index.html.erb

 <!---LOAD MORE POST BUTTON-->
        <div class="float-right" style="z-index: 1000;">
          <%= link_to load_more_path(@posts.last.id), class: 'bttn-material-circle bttn-danger bttn-md load-more-posts', :remote => true do %>
            <i class="fas fa-sync"></i>
          <% end %>
        </div>

I'm using friendly_id to hash ids for posts. 我正在使用friendly_id对帖子的ID进行哈希处理。

On your logs, you can see the load_more request has a really weird extension: 在您的日志上,您可以看到load_more请求具有一个非常奇怪的扩展名:

Started GET "/load_more.%23%3CPost::ActiveRecord_Relation:0x0000000016f89718%3E"

Rails think's that's the format and does not know how to render that format. Rails认为那是格式,不知道如何呈现该格式。

Your route is defined like this: 您的路线定义如下:

get "/load_more", to: "posts#load_more", as: 'load_more'

but you are using it like this 但是你这样使用它

load_more_path(@posts)

and the route does not expect a parameter and it ends up using it as a format. 并且路由不希望有参数,因此最终将其用作格式。

You should add something to the route so you know from what post "load more". 您应该在路线中添加一些内容,以便从哪个帖子中了解“加载更多”信息。 I'll do something like: 我会做类似的事情:

get "/load_more/:last_post_id", to: "posts#load_more", as: 'load_more'

And use it like 并像这样使用

load_more_path(@posts.last.id)

And on the controller you'll have access to params[:last_post_id] so you know you need to load more posts after that post id. 在控制器上,您可以访问params[:last_post_id]因此您知道需要在该帖子ID之后加载更多帖子。

following_ids = current_user.following_users.pluck(:id)
following_ids << current_user.id
@posts = Post.where(user_id: params[:following_ids]).where('id < ?', params[:last_post_id]).order('created_at DESC').limit(20)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM