I'm using active_model_serializers
gem in my application to send high level json response. It does actually works fine but since I've install that gem, after few minutes of use, the application crash, showing the error above.
Not sure if my code is related to it but somehow, I needed to send back some partial as well. Since it didn't seems to be supported by the gem, I did a work around :
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
Then, in my serializer, I can do :
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
This code works fine, and I'm getting my partial as JSON attributes. The weird thing is that the error appears progressively on any page. The only way to remove it is by restarting the server. But again, after few minutes of use, the problem comes back.
Here is a part of the log :
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'
Any of you already face something similar?
EDIT :
As requested, here is the code of my view :
%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
EDIT 2 :
After digging a bit more, I found out that this code :
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
when calling is overriding Rails helpers and loading libraries, which cause the entire system to be unworking. However, how can I fix it?
Ok, I finally found a work around. The problem really came from my edit 2 point in the above post.
To fix it, since I was already using the rails_config
gem (https://github.com/railsjedi/rails_config) in my app, I've used it in order to be able to render my partials directly from my serializer without breaking the Rails magic autoloading.
First, I'm setting up the context as a config (Settings) :
# application_controller
class ApplicationController < ActionController::Base
before_filter :set_context_for_serializer
def set_context_for_serializer
Settings.context = self
end
end
Then, within my serializer, all I need to do is :
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
And that's it, now it works perfectly. If you guys have some other way (more Rails like) to do it, I'll be curious to know about it.
Thanks
来源:https://stackoverflow.com/questions/24281339/active-model-serializers-undefined-method-url-for-for-nilnilclass