undefined method 'change' for :Fixnum when updating Timestamp value

核能气质少年 提交于 2020-01-15 08:58:33

问题


I'm using Google's OAuth2 API in a project, using Omniauth to enable creating the initial accounts with little effort, but in order to use the APIs I need to refresh the access_token since they're only valid for an hour, but I'm having an issue updating the expires_at value when I refresh the token.

Here's the code I'm using for requesting the token refresh:

require 'oauth2'
class Identity < ActiveRecord::Base
belongs_to :user
  def refresh_access_token
    case self.provider
      when "google"
        client = OAuth2::Client.new OAUTH_KEYS_CONFIG['google']['client_id'], 
                                    OAUTH_KEYS_CONFIG['google']['client_secret'],
                                    {
                                      :site => 'https://accounts.google.com',
                                      :authorize_url => "/o/oauth2/auth",
                                      :token_url => "/o/oauth2/token"
                                    }
        response = OAuth2::AccessToken.from_hash(client, :refresh_token => self.refresh_token).refresh!

        self.update_attribute(:access_token, response.token)
        self.update_attribute(:expires_at, Time.at(response.expires_at))
    end
  end
end

I get an undefined method 'change' for 1359936923:Fixnum error on the final update_attribute line for :expires_at (I split it from the line above to try and figure out the issue).

I've tried both the above update_attribute call, and also a simple self.expires_at = response.expires_at, with and without Time.at casting but all combinations result in the same error.

The :expires_at attribute is a Timestamp datatype. I've checked the response variable, it contains the timestamp correctly as far as I can tell:

--- !ruby/object:OAuth2::AccessToken
...
expires_in: 3600
expires_at: 1360019618
options:
  :mode: :header
  :header_format: Bearer %s
  :param_name: bearer_token
...

Stack trace

activerecord (3.2.11) lib/active_record/attribute_methods/time_zone_conversion.rb:69:in `round_usec'
activerecord (3.2.11) lib/active_record/attribute_methods/time_zone_conversion.rb:46:in `expires_at='
activerecord (3.2.11) lib/active_record/persistence.rb:180:in `update_attribute'
app/models/identity.rb:69:in `refresh_access_token'
app/controllers/sessions_controller.rb:30:in `create'
actionpack (3.2.11) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
actionpack (3.2.11) lib/abstract_controller/base.rb:167:in `process_action'
actionpack (3.2.11) lib/action_controller/metal/rendering.rb:10:in `process_action'
actionpack (3.2.11) lib/abstract_controller/callbacks.rb:18:in `block in process_action'
activesupport (3.2.11) lib/active_support/callbacks.rb:414:in `_run__3108124736639590412__process_action__2258996443485139522__callbacks'
activesupport (3.2.11) lib/active_support/callbacks.rb:405:in `__run_callback'
activesupport (3.2.11) lib/active_support/callbacks.rb:385:in `_run_process_action_callbacks'
activesupport (3.2.11) lib/active_support/callbacks.rb:81:in `run_callbacks'
actionpack (3.2.11) lib/abstract_controller/callbacks.rb:17:in `process_action'
actionpack (3.2.11) lib/action_controller/metal/rescue.rb:29:in `process_action'
actionpack (3.2.11) lib/action_controller/metal/instrumentation.rb:30:in `block in process_action'
activesupport (3.2.11) lib/active_support/notifications.rb:123:in `block in instrument'
activesupport (3.2.11) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
activesupport (3.2.11) lib/active_support/notifications.rb:123:in `instrument'
actionpack (3.2.11) lib/action_controller/metal/instrumentation.rb:29:in `process_action'
actionpack (3.2.11) lib/action_controller/metal/params_wrapper.rb:207:in `process_action'
activerecord (3.2.11) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
actionpack (3.2.11) lib/abstract_controller/base.rb:121:in `process'
actionpack (3.2.11) lib/abstract_controller/rendering.rb:45:in `process'
actionpack (3.2.11) lib/action_controller/metal.rb:203:in `dispatch'
actionpack (3.2.11) lib/action_controller/metal/rack_delegation.rb:14:in `dispatch'
actionpack (3.2.11) lib/action_controller/metal.rb:246:in `block in action'
actionpack (3.2.11) lib/action_dispatch/routing/route_set.rb:73:in `call'
actionpack (3.2.11) lib/action_dispatch/routing/route_set.rb:73:in `dispatch'
actionpack (3.2.11) lib/action_dispatch/routing/route_set.rb:36:in `call'
journey (1.0.4) lib/journey/router.rb:68:in `block in call'
journey (1.0.4) lib/journey/router.rb:56:in `each'
journey (1.0.4) lib/journey/router.rb:56:in `call'
actionpack (3.2.11) lib/action_dispatch/routing/route_set.rb:601:in `call'
omniauth (1.1.1) lib/omniauth/strategy.rb:394:in `call_app!'
omniauth (1.1.1) lib/omniauth/strategy.rb:356:in `callback_phase'
omniauth-oauth2 (1.1.1) lib/omniauth/strategies/oauth2.rb:77:in `callback_phase'
omniauth (1.1.1) lib/omniauth/strategy.rb:219:in `callback_call'
omniauth (1.1.1) lib/omniauth/strategy.rb:175:in `call!'
omniauth (1.1.1) lib/omniauth/strategy.rb:157:in `call'
omniauth (1.1.1) lib/omniauth/builder.rb:48:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/best_standards_support.rb:17:in `call'
rack (1.4.4) lib/rack/etag.rb:23:in `call'
rack (1.4.4) lib/rack/conditionalget.rb:25:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/head.rb:14:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/params_parser.rb:21:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/flash.rb:242:in `call'
rack (1.4.4) lib/rack/session/abstract/id.rb:210:in `context'
rack (1.4.4) lib/rack/session/abstract/id.rb:205:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/cookies.rb:341:in `call'
activerecord (3.2.11) lib/active_record/query_cache.rb:64:in `call'
activerecord (3.2.11) lib/active_record/connection_adapters/abstract/connection_pool.rb:479:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/callbacks.rb:28:in `block in call'
activesupport (3.2.11) lib/active_support/callbacks.rb:405:in `_run__2408988688759615157__call__236505231918019627__callbacks'
activesupport (3.2.11) lib/active_support/callbacks.rb:405:in `__run_callback'
activesupport (3.2.11) lib/active_support/callbacks.rb:385:in `_run_call_callbacks'
activesupport (3.2.11) lib/active_support/callbacks.rb:81:in `run_callbacks'
actionpack (3.2.11) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/reloader.rb:65:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/remote_ip.rb:31:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/debug_exceptions.rb:16:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/show_exceptions.rb:56:in `call'
railties (3.2.11) lib/rails/rack/logger.rb:32:in `call_app'
railties (3.2.11) lib/rails/rack/logger.rb:16:in `block in call'
activesupport (3.2.11) lib/active_support/tagged_logging.rb:22:in `tagged'
railties (3.2.11) lib/rails/rack/logger.rb:16:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/request_id.rb:22:in `call'
rack (1.4.4) lib/rack/methodoverride.rb:21:in `call'
rack (1.4.4) lib/rack/runtime.rb:17:in `call'
activesupport (3.2.11) lib/active_support/cache/strategy/local_cache.rb:72:in `call'
rack (1.4.4) lib/rack/lock.rb:15:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/static.rb:62:in `call'
railties (3.2.11) lib/rails/engine.rb:479:in `call'
railties (3.2.11) lib/rails/application.rb:223:in `call'
rack (1.4.4) lib/rack/content_length.rb:14:in `call'
railties (3.2.11) lib/rails/rack/log_tailer.rb:17:in `call'
thin (1.5.0) lib/thin/connection.rb:81:in `block in pre_process'
thin (1.5.0) lib/thin/connection.rb:79:in `catch'
thin (1.5.0) lib/thin/connection.rb:79:in `pre_process'
thin (1.5.0) lib/thin/connection.rb:54:in `process'
thin (1.5.0) lib/thin/connection.rb:39:in `receive_data'
eventmachine (1.0.0) lib/eventmachine.rb:187:in `run_machine'
eventmachine (1.0.0) lib/eventmachine.rb:187:in `run'
thin (1.5.0) lib/thin/backends/base.rb:63:in `start'
thin (1.5.0) lib/thin/server.rb:159:in `start'
rack (1.4.4) lib/rack/handler/thin.rb:13:in `run'
rack (1.4.4) lib/rack/server.rb:268:in `start'
railties (3.2.11) lib/rails/commands/server.rb:70:in `start'
railties (3.2.11) lib/rails/commands.rb:55:in `block in <top (required)>'
railties (3.2.11) lib/rails/commands.rb:50:in `tap'
railties (3.2.11) lib/rails/commands.rb:50:in `<top (required)>'
script/rails:6:in `require'
script/rails:6:in `<main>'

回答1:


If you can get away with it, you can turn off time zone awareness for your attribute, expires_at.

class Identity < ActiveRecord::Base
  self.skip_time_zone_conversion_for_attributes = [:expires_at]
end

We are seeing the same issue because we have a Android app sending an Epoch time back to our website. Turning off time zone conversion for that attribute got rid of the error and so far seems to have no ill effects on the data. Of course, we're storing everything in UTC and so far this seems to be the only work around.

Some resources:

  • http://api.rubyonrails.org/classes/ActiveRecord/Timestamp.html
  • https://github.com/rails/rails/blob/master/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb


来源:https://stackoverflow.com/questions/14696863/undefined-method-change-for-fixnum-when-updating-timestamp-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!