Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

与rails 5/6存在冲突,不知道是哪一方有问题 #165

Open
freefishz opened this issue Dec 1, 2016 · 13 comments
Open

与rails 5/6存在冲突,不知道是哪一方有问题 #165

freefishz opened this issue Dec 1, 2016 · 13 comments

Comments

@freefishz
Copy link

rails 5 + jbuilder 2.6 + WeChat 0.8.3, 会导致api json输出body部分为空。具体问题见以下链接https://github.com/rails/jbuilder/issues/346中charleyw的回复。

@Eric-Guo
Copy link
Owner

Eric-Guo commented Dec 1, 2016

@charleyw 我的理解是如果使用了jbuilder,还使用了WeChat,会导致jbuilder输出问题?我自己的项目已经用了jbuilder 2.6.1,似乎没有这个问题?测试也无法复现,能给个可复现的例子么?最好是rspec的failure的测试。

@freefishz
Copy link
Author

freefishz commented Dec 2, 2016

昨天用pry-byebug跟踪了一下,发现不是jbuilder的问题,是和rails5有冲突。
wechat_responder.rb,中添加

  if defined? Base
    class << Base
      include WechatResponder
    end
  end

  if defined? API
    class << API
      include WechatResponder
    end
  end

后,在controller中查看祖先链时,发现少了ActionView::Rendering,导致了不能render正确的模板。ActionView::Rendering中有个方法_normalize_options,用于设置render的模板(jbuilder的模板)。如果缺少了这个模块,就会再往上调用祖先的_normalize_options,就会导致模板丢失,也就不render了。

=> [Api::V1::HomesController,
 #<Module:0x000000061d6d10>,
 Api::V1::ApplicationController,
 Knock::Authenticable,
 #<Module:0x00000006231300>,
 #<Module:0x000000064458d0>,
 #<Module:0x000000064458f8>,
 ActionController::API,
 ActionController::ImplicitRender,
 ActionController::Helpers,
 AbstractController::Helpers,
 ActiveRecord::Railties::ControllerRuntime,
 ActionDispatch::Routing::RouteSet::MountedHelpers,
 ActionController::ParamsWrapper,
 ActionController::Instrumentation,
 ActionController::Rescue,
 ActionController::DataStreaming,
 ActionController::ForceSSL,
 AbstractController::Callbacks,
 ActiveSupport::Callbacks,
 ActionController::StrongParameters,
 ActiveSupport::Rescuable,
 ActionController::BasicImplicitRender,
 ActionController::ConditionalGet,
 ActionController::Head,
 ActionController::Renderers::All,
 ActionController::Renderers,
 ActionController::Rendering,
 ActionController::ApiRendering,
 -------就是这个> ActionView::Rendering,
 ActionController::Redirecting,
 ActiveSupport::Benchmarkable,
 AbstractController::Logger,
 ActionController::UrlFor,
 AbstractController::UrlFor,
 ActionDispatch::Routing::UrlFor,
 ActionDispatch::Routing::PolymorphicRoutes,
 AbstractController::Rendering,
 ActionView::ViewPaths,
 #<Module:0x00000003381fc8>,
 ActionController::Metal,
 ActionController::Testing::Functional,
 AbstractController::Base,
 ActiveSupport::Configurable,
 ActiveSupport::ToJsonWithActiveSupportEncoder,
 Object,
 PP::ObjectMixin,
 ActiveSupport::Dependencies::Loadable,
 JSON::Ext::Generator::GeneratorMethods::Object,
 ActiveSupport::Tryable,
 Kernel,
 BasicObject]

如果注释掉wechat_responder.rb中的那段代码,ActionView::Rendering就回来了。
而且发现,只要在wechat_responder.rb中将对上述注释掉的代码改为仅打开API,也会出现同样的问题,比如:

module ActionController
  class API 
  end
end

至于为何会导致ActionView::Rendering丢失,还在研究。

@freefishz freefishz changed the title 与jbuilder gem存在冲突,不知道是哪一方有问题 与rails 5存在冲突,不知道是哪一方有问题 Dec 2, 2016
@charleyw
Copy link

charleyw commented Dec 2, 2016

刚才看了一下,这个问题只有在rails 5的API模式下才能重现。

@yorkxin
Copy link

yorkxin commented Dec 9, 2016

我也遇到了同樣的問題,但沒有使用你們的 wechat gem。

我是把原本 app 裡面繼承 ActonController::Base 的 api 改成繼承 ActionController::API 從而發現問題。從頭 rails new 一個 app 則沒有這個問題。

@xwangzhaox
Copy link

xwangzhaox commented Dec 15, 2016

我的环境是rails5 API的,也遇到了类似的问题
如果直接在controller里引用wechat_api,启服务时则会提示找不到
undefined local variable or method wechat_api' for XxxController:Class`

如果把继承换成ActionController::Base则没问题,但是不能那么干:)
看了源码后,有样学样加了这样一段在controller里,就能通过了
module ActionController class << API include WechatResponder end end

那么有两个问题:

  1. 在wechat_responder.rb中,以下这段代码明显是把include默认加到了ActionController::Base中而不是API,这个是为啥?
    if defined? Base class << Base include WechatResponder end elsif defined? API class << API include WechatResponder end end

  2. 如果我不是把include加在ActionController::API中而是直接放到我自己的controller中,则会提示``class:XxxController': uninitialized constant WechatResponder (NameError)`这是为什么?

@freefishz
Copy link
Author

暂时可以通过手工添加include ActionView::Rendering来解决这个问题:

class ApplicationController < ActionController::API
  include ActionView::Rendering
end

Eric-Guo referenced this issue in sandect/wechat Mar 12, 2017
@Eric-Guo Eric-Guo reopened this Mar 13, 2017
@numbcoder
Copy link

这个问题暂时还没解决,引入 wechat 这个 gem 后,jbuilder 的输出就是空的,引入 include ActionView::Rendering 后,能解决 jbuilder 的问题,但是 render json: {ok: 1} 这种又不能用了。。

个人认为,插件最好不要修改框架底层的东西

@mysterytree
Copy link

wechat (0.8.8)出现同样的问题
会退到wechat (0.8.4)就好了

@Eric-Guo
Copy link
Owner

Eric-Guo commented Jun 8, 2017

@mysterytree 能在本地改一下最新0.8.8的这几行确认一下么?

bundle open wechat # edit lib/action_controller/wechat_responder.rb:L66
  if defined? Base
    class << Base
      include WechatResponder
    end
  elsif defined? API
    class << API
      include WechatResponder
    end
  end

@Eric-Guo Eric-Guo reopened this Jun 8, 2017
@LSkipJackie
Copy link

LSkipJackie commented Aug 5, 2017

能在本地改一下最新0.8.8的这几行确认一下么?

@Eric-Guo 实测0.8.11是无法在rails5 api下正常显示json返回的结果的。在0.8.11下按上面回复的修改后可以正常显示出json返回的结果的

但是修改之后GET访问 /wechat 是会报错的,错误信息为“undefined local variable or method `wechat_responder' for WechatsController:Class”

@Youngv
Copy link

Youngv commented Dec 21, 2017

@numbcoder 找到了一个解决方法,在 Rails 5.1.4 + Jbuilder 2.7.0 + wechat 0.8.12 可以正常使用

class ApplicationController < ActionController::API
  include ActionView::Rendering

  def render_to_body(options)
    _render_to_body_with_renderer(options) || super
  end
end

@ifsc01
Copy link

ifsc01 commented Aug 19, 2019

@numbcoder 一样,jbuilder 和 render: json 不能同时用

@Eric-Guo
Copy link
Owner

Eric-Guo commented Dec 5, 2019

今天我也遇到了,直接include 可解,Rails 6.0.1

  class EventsController < ActionController::API
    include ActionView::Rendering
    # Support render json: nil
    def render_to_body(options)
      _render_to_body_with_renderer(options) || super
    end
  end

@Eric-Guo Eric-Guo pinned this issue Oct 10, 2020
@Eric-Guo Eric-Guo changed the title 与rails 5存在冲突,不知道是哪一方有问题 与rails 5/6存在冲突,不知道是哪一方有问题 Feb 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants