使用acts_as_votable实现无刷新点赞时模板缺失问题求助
无刷新点赞功能的模板缺失问题排查
已基于acts_as_votable gem实现页面刷新点赞,现在尝试通过AJAX实现无刷新点赞,项目存在partial嵌套结构,当前遇到ActionView::MissingTemplate错误,提示找不到events/favorite.js.erb模板,已尝试多路径放置文件仍未解决,以下是相关代码、错误信息及排查思路:
相关代码
1. events/index.html.erb(渲染partial)
<div class="event-list-wrapper"> <% @events.upcoming_events.each do |event| %> <%= render 'event', event: event %> <% end %> </div>
2. _event.html.erb partial
<div class="card shadow rounded mb-3"> <div class="top-card"> <div class="card-image"> <% if event.event_image.attached? %> <%= link_to image_tag(event.event_image, class: "card-img-top event-index-image").html_safe, event %> <% else %> <img src="https://dancewise.s3.amazonaws.com/Blank+Event+Image.png" class="card-img-top even-size-event"> <% end %> </div> <div class="heart-container"> <%= render "events/favorite-link", event: event %> </div> </div>
3. _favorite-link.html.erb partial
<%= content_tag "div", id: "upvote-#{event.id}" do %> <%= link_to upvote_event_path(event), method: :get, remote: true do %> <% if current_user.voted_up_on? event %> <%= link_to upvote_event_path(event), method: :patch do %> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#ff2929" stroke-width="1.2" stroke="#f2f2f2" class="w-6 h-6"> <path d="M11.645 20.91l-.007-.003-.022-.012a15.247 15.247 0 01-.383-.218 25.18 25.18 0 01-4.244-3.17C4.688 15.36 2.25 12.174 2.25 8.25 2.25 5.322 4.714 3 7.688 3A5.5 5.5 0 0112 5.052 5.5 5.5 0 0116.313 3c2.973 0 5.437 2.322 5.437 5.25 0 3.925-2.438 7.111-4.739 9.256a25.175 25.175 0 01-4.244 3.17 15.247 15.247 0 01-.383.219l-.022.012-.007.004-.003.001a.752.752 0 01-.704 0l-.003-.001z" /> </svg> <% end %> <% else %> <%= link_to upvote_event_path(event), method: :patch do %> <svg xmlns="http://www.w3.org/2000/svg" fill="#000000" fill-opacity="0.5" viewBox="0 0 24 24" data-user-logged-in="<%= user_signed_in? %>" stroke-width="1.2" stroke="#f2f2f2" class="w-6 h-6"> <path stroke-linecap="round" stroke-linejoin="round" d="M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12z" /> </svg> <% end %> <% end %> <% end %> <% end %>
4. favorite.js.erb 代码
document.getElementById("upvote-<%= @event.id %>").innerHTML = "<%= j render "events/favorite-link", event: event %>";
5. events_controller.rb 的 upvote 方法
def upvote if current_user.voted_up_on? @event @event.unvote_by current_user else @event.upvote_by current_user end render "favorite.js.erb" end
6. routes.rb 相关代码
resources :events do member do get "upvote", to: "events#upvote" end end
文件放置路径
/Users/ogarocious/Desktop/RubyWorld/wherecanwedance-dw/app/views/favorite.js.erb/Users/ogarocious/Desktop/RubyWorld/wherecanwedance-dw/app/views/events/favorite.js.erb
错误日志
01:58:49 web.1 | Completed 500 Internal Server Error in 24ms (ActiveRecord: 4.5ms | Allocations: 10048) 01:58:49 web.1 | 01:58:49 web.1 | ActionView::MissingTemplate (Missing template events/favorite.js.erb, application/favorite.js.erb with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :jbuilder]}. 01:58:49 web.1 | 01:58:49 web.1 | Searched in: 01:58:49 web.1 | * "/Users/ogarocious/Desktop/RubyWorld/wherecanwedance-dw/app/views" 01:58:49 web.1 | * "/Users/ogarocious/.rvm/gems/ruby-3.0.2/gems/devise-4.8.1/app/views" 01:58:49 web.1 | * "/Users/ogarocious/.rvm/gems/ruby-3.0.2/gems/actiontext-7.0.4/app/views" 01:58:49 web.1 | * "/Users/ogarocious/.rvm/gems/ruby-3.0.2/gems/actionmailbox-7.0.4/app/views" 01:58:49 web.1 | 01:58:49 web.1 | app/controllers/events_controller.rb:19:in `upvote'
排查思路
修正请求格式:错误日志显示请求格式为
[:html],但AJAX需要js格式。可以:- 修改路由为
get "upvote", to: "events#upvote", format: :js - 或在
link_to中指定格式:upvote_event_path(event, format: :js)
- 修改路由为
明确模板渲染路径:在控制器中指定完整路径和格式,避免歧义:
# 如果模板在events目录下 render template: "events/favorite", formats: :js # 如果模板在根视图目录 render template: "favorite", formats: :js修复JS模板变量错误:
favorite.js.erb中使用了未定义的event变量,应改为控制器中的@event:document.getElementById("upvote-<%= @event.id %>").innerHTML = "<%= j render "events/favorite-link", event: @event %>";调整路由请求方法:点赞/取消点赞是修改操作,不应使用
get,改为patch:resources :events do member do patch "upvote", to: "events#upvote" end end清理嵌套的
link_to:当前代码中嵌套了两层link_to,会生成无效的嵌套<a>标签,导致AJAX请求失效,重构为:<%= content_tag "div", id: "upvote-#{event.id}" do %> <% if current_user.voted_up_on? event %> <%= link_to upvote_event_path(event, format: :js), method: :patch, remote: true do %> <!-- 已点赞SVG --> <% end %> <% else %> <%= link_to upvote_event_path(event, format: :js), method: :patch, remote: true do %> <!-- 未点赞SVG --> <% end %> <% end %> <% end %>
内容的提问来源于stack exchange,提问作者Ogarocious
相关产品推荐
相关产品推荐

