2014-06-18 31 views
3

我在我的應用程序中使用active_model_serializers gem來發送高級別json響應。它確實工作正常,但由於我已經安裝了該寶石,經過幾分鐘的使用後,應用程序崩潰,顯示上述錯誤。活動模型序列化程序:未定義方法`url_for'爲零:NilClass

不知道我的代碼是否與它有關,但不知何故,我需要發回一些部分。因爲它沒有似乎是由寶石的支持,我做了變通:

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 

當呼叫被覆蓋時g Rails助手和加載庫,這會導致整個系統無法工作。但是,我該如何解決它?

+0

你能告訴什麼在發生的事情:'應用程序/視圖/活動/ _post.html.haml' –

+0

我不認爲這個問題來自於視圖,雖然,因爲它發生在所有頁面上逐步。此外,當通過「ActiveModel :: Serializer」請求(使用Ajax)這個部分時,我得到它並使用Angular將它注入DOM,並且它正在工作。 – lkartono

+0

我在使用時遇到過同樣的問題 view.class.class_eval do include Rails.application.routes.url_helpers include ApplicationHelper end –

回答

1

好吧,我終於找到了解決辦法。該問題確實來自我在上述帖子中的編輯2點。

要修復它,因爲我已經用我的應用程序的rails_config寶石(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),我會很好奇的知道它。

感謝

相關問題