我在我的应用程序中使用active_model_serializers
gem来发送高级json响应。它实际上工作正常但是因为我已经安装了这个gem,使用几分钟后,应用程序崩溃,显示上面的错误。
不确定我的代码是否与它有关但不知何故,我还需要发回部分代码。由于它似乎没有得到宝石的支持,我做了一个解决方法:
class AppSerializer < ActiveModel::Serializer
def render_partial_to_json(options = {})
partial = options[:partial] || nil
locals = options[:locals] || nil
context = Rails.configuration.paths['app/views']
view = ActionView::Base.new(context)
view.class.class_eval do
include Rails.application.routes.url_helpers
include ApplicationHelper
end
view.render(
partial: partial,
locals: locals
)
end
end
然后,在我的序列化器中,我可以这样做:
class ActivitySerializer < AppSerializer
attributes :id, :kind, :data, :created_at, :html
has_many :comments
has_one :user
def id
ScatterSwap.hash(object.id)
end
def html
render_partial_to_json(
partial: 'activities/post',
locals: { activity: object }
)
end
end
此代码工作正常,我将部分视为JSON属性。 奇怪的是,错误在任何页面上逐渐出现。删除它的唯一方法是重新启动服务器。但是,经过几分钟的使用后,问题又回来了。
以下是日志的一部分:
Completed 500 Internal Server Error in 65ms
NoMethodError - undefined method `url_for' for nil:NilClass:
actionpack (4.0.3) lib/action_dispatch/routing/url_for.rb:155:in `url_for'
actionpack (4.0.3) lib/action_view/routing_url_for.rb:83:in `url_for'
turbolinks (2.2.1) lib/turbolinks/xhr_url_for.rb:12:in `url_for_with_xhr_referer'
actionpack (4.0.3) lib/action_dispatch/routing/route_set.rb:234:in `call'
actionpack (4.0.3) lib/action_dispatch/routing/route_set.rb:178:in `call'
actionpack (4.0.3) lib/action_dispatch/routing/route_set.rb:274:in `block (2 levels) in define_url_helper'
app/views/activities/_post.html.haml:2:in `_app_views_activities__post_html_haml__1000109198282705156_2214339020'
actionpack (4.0.3) lib/action_view/template.rb:143:in `block in render'
activesupport (4.0.3) lib/active_support/notifications.rb:161:in `instrument'
actionpack (4.0.3) lib/action_view/template.rb:141:in `render'
actionpack (4.0.3) lib/action_view/renderer/partial_renderer.rb:306:in `render_partial'
actionpack (4.0.3) lib/action_view/renderer/partial_renderer.rb:279:in `block in render'
actionpack (4.0.3) lib/action_view/renderer/abstract_renderer.rb:38:in `block in instrument'
activesupport (4.0.3) lib/active_support/notifications.rb:159:in `block in instrument'
activesupport (4.0.3) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
activesupport (4.0.3) lib/active_support/notifications.rb:159:in `instrument'
actionpack (4.0.3) lib/action_view/renderer/abstract_renderer.rb:38:in `instrument'
actionpack (4.0.3) lib/action_view/renderer/partial_renderer.rb:278:in `render'
actionpack (4.0.3) lib/action_view/renderer/renderer.rb:47:in `render_partial'
actionpack (4.0.3) lib/action_view/helpers/rendering_helper.rb:27:in `render'
haml (4.1.0.beta.1) lib/haml/helpers/action_view_mods.rb:10:in `block in render_with_haml'
haml (4.1.0.beta.1) lib/haml/helpers.rb:89:in `non_haml'
你们中的任何一个人已经面临过类似的事情
编辑:
根据要求,这是我的观点代码:
%article#comment-id-1.comment-item.m-t
= link_to profile_url(activity.user), class: "pull-left thumb-sm avatar" do
= display_picture_for activity.user, resizing_by: "36x36"
%span.arrow.left
%section.comment-body.panel.panel-default
%header.panel-heading.bg-white
= link_to profile_url(activity.user) do
= activity.user.fullname
%span.text-muted.m-l-sm.pull-right
%i.fa.fa-clock-o
= time_ago_in_words activity.created_at
.panel-body
%div
= activity.data[:message]
.comment-action.m-t-sm
%a.btn.btn-default.btn-xs.active{"data-toggle" => "class", href: "#"}
%i.fa.fa-star-o.text-muted.text
%i.fa.fa-star.text-danger.text-active
Like
%a.btn.btn-default.btn-xs{href: "#comment-form"}
%i.fa.fa-mail-reply.text-muted
Reply
编辑2:
经过多挖掘后,我发现这段代码:
class AppSerializer < ActiveModel::Serializer
def render_partial_to_json(options = {})
partial = options[:partial] || nil
locals = options[:locals] || nil
context = Rails.configuration.paths['app/views']
view = ActionView::Base.new(context)
view.class.class_eval do
include Rails.application.routes.url_helpers
include ApplicationHelper
end
view.render(
partial: partial,
locals: locals
)
end
end
当调用覆盖Rails助手和加载库时,会导致整个系统不工作。但是,我该如何解决呢?
答案 0 :(得分:2)
好的,我终于找到了解决方法。问题确实来自上面帖子中的编辑2 点。
要修复它,因为我已经在我的应用中使用rails_config
gem(https://github.com/railsjedi/rails_config),我已经使用它以便能够直接从我的序列化器渲染我的部分而不会破坏Rails魔术自动加载。
首先,我将上下文设置为配置(设置):
# application_controller
class ApplicationController < ActionController::Base
before_filter :set_context_for_serializer
def set_context_for_serializer
Settings.context = self
end
end
然后,在我的序列化器中,我需要做的就是:
class ApplicationSerializer < ActiveModel::Serializer
def render_partial_to_json(options = {})
partial = options[:partial] || nil
locals = options[:locals] || nil
Settings.context.render_to_string(
partial: partial,
layout: false,
formats: :html,
locals: locals
)
end
end
class ActivitySerializer < ApplicationSerializer
attributes :id, :kind, :data, :created_at, :html
def html
render_partial_to_json(
partial: 'activities/post',
locals: { activity: object }
)
end
end
就是这样,现在它完美无缺。如果你们有其他方式(更像Rails),我会很想知道它。
由于