8 votes

rails 4 activerecord TypeError nil n'est pas un symbole

Il semble qu'une table dans le serveur SQL place nil dans l'instruction select. Je n'ai aucune idée de la manière de résoudre ce problème, et si je passe à une autre table, je peux facilement obtenir le premier enregistrement. Quelqu'un d'autre a-t-il rencontré ce problème ? J'ai démonté la table et construit une vue. Le problème persiste. J'hésite à appliquer un correctif. Des idées ? Comment je me connecte à sql server :

Mon modèle :

class Deal < ActiveRecord::Base
  self.table_name = 'vwStorePromosExtSummaryGlobal'
end

Mon contrôleur :

class V1::DealsController < ApplicationController
    def by_mall_id
      deals = Deal.where(mallid: params[:id])
      render json: deals
    end
end

# Use sqlserver as the database for Active Record
gem 'tiny_tds', '~> 0.6.1'
gem 'activerecord-sqlserver-adapter', github: 'arthrex/activerecord-sqlserver-adapter'
gem 'active_model_serializers', '~> 0.8.1'

Lorsque j'ouvre l'erreur exacte dans la gemme, je vois :

     97:     def serializable_hash(options = nil)
     98:       options ||= {}
     99:
    100:       attribute_names = attributes.keys
    101:       if only = options[:only]
    102:         attribute_names &= Array(only).map(&:to_s)
    103:       elsif except = options[:except]
    104:         attribute_names -= Array(except).map(&:to_s)
    105:       end
    106:
    107:       hash = {}
    108:
 => 109: binding.pry
    110:
    111:       attribute_names.each { |n| hash[n] = read_attribute_for_serialization(n) }
    112:
    113:       Array(options[:methods]).each { |m| hash[m.to_s] = send(m) if respond_to?(m) }
    114:
    115:       serializable_add_includes(options) do |association, records, opts|
    116:         hash[association.to_s] = if records.respond_to?(:to_ary)
    117:           records.to_ary.map { |a| a.serializable_hash(opts) }
    118:         else
    119:           records.serializable_hash(opts)
    120:         end
    121:       end
    122:
    123:       hash
    124:     end

[1] pry(#<Deal>)> p attribute_names.each
#<Enumerator: ["mallid", nil]:each>
=> #<Enumerator: ...>
[2] pry(#<Deal>)> p attribute_names
["mallid", nil]
=> ["mallid", nil]
[3] pry(#<Deal>)>

Voici ma trace complète :

  [1m[36mSQL (49.6ms)[0m  [1mUSE [pcmenu][0m
Processing by V1::DealsController#by_mall_id as JSON
  Parameters: {"id"=>"1066"}
  [1m[35mDeal Load (44.5ms)[0m  EXEC sp_executesql N'SELECT TOP (1) mallid FROM [StorePromosExtSummaryGlobal] WHERE [StorePromosExtSummaryGlobal].[mallid] = N''1066'' AND (salestypeid = 11
 AND calcendDate > ''09-09-2013''
 AND displayDate < ''09-09-2013''
 AND (promoType is null or promoType = 0)) ORDER BY displayName ASC'
Completed 500 Internal Server Error in 546ms

TypeError - nil is not a symbol:
  activemodel (4.0.0) lib/active_model/serialization.rb:108:in `block in serializable_hash'
  activemodel (4.0.0) lib/active_model/serialization.rb:108:in `serializable_hash'
  activerecord (4.0.0) lib/active_record/serialization.rb:17:in `serializable_hash'
  activemodel (4.0.0) lib/active_model/serializers/json.rb:99:in `as_json'
  activesupport (4.0.0) lib/active_support/json/encoding.rb:50:in `block in encode'
  activesupport (4.0.0) lib/active_support/json/encoding.rb:81:in `check_for_circular_references'
  activesupport (4.0.0) lib/active_support/json/encoding.rb:49:in `encode'
  activesupport (4.0.0) lib/active_support/json/encoding.rb:34:in `encode'
  activesupport (4.0.0) lib/active_support/core_ext/object/to_json.rb:16:in `to_json'
  actionpack (4.0.0) lib/action_controller/metal/renderers.rb:90:in `block in <module:Renderers>'
  active_model_serializers (0.8.1) lib/action_controller/serialization.rb:48:in `_render_option_json'
  actionpack (4.0.0) lib/action_controller/metal/renderers.rb:33:in `block in _handle_render_options'
  /Users/chrishough/.rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/set.rb:232:in `each'
  actionpack (4.0.0) lib/action_controller/metal/renderers.rb:30:in `_handle_render_options'
  actionpack (4.0.0) lib/action_controller/metal/renderers.rb:26:in `render_to_body'
  actionpack (4.0.0) lib/abstract_controller/rendering.rb:97:in `render'
  actionpack (4.0.0) lib/action_controller/metal/rendering.rb:16:in `render'
  actionpack (4.0.0) lib/action_controller/metal/instrumentation.rb:41:in `block (2 levels) in render'
  activesupport (4.0.0) lib/active_support/core_ext/benchmark.rb:12:in `block in ms'
  /Users/chrishough/.rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/benchmark.rb:296:in `realtime'
  activesupport (4.0.0) lib/active_support/core_ext/benchmark.rb:12:in `ms'
  actionpack (4.0.0) lib/action_controller/metal/instrumentation.rb:41:in `block in render'
  actionpack (4.0.0) lib/action_controller/metal/instrumentation.rb:84:in `cleanup_view_runtime'
  activerecord (4.0.0) lib/active_record/railties/controller_runtime.rb:25:in `cleanup_view_runtime'
  actionpack (4.0.0) lib/action_controller/metal/instrumentation.rb:40:in `render'
  app/controllers/v1/deals_controller.rb:6:in `by_mall_id'
  apipie-rails (0.0.22) lib/apipie/dsl_definition.rb:193:in `block in _apipie_define_validators'
  actionpack (4.0.0) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
  actionpack (4.0.0) lib/abstract_controller/base.rb:189:in `process_action'
  actionpack (4.0.0) lib/action_controller/metal/rendering.rb:10:in `process_action'
  actionpack (4.0.0) lib/abstract_controller/callbacks.rb:18:in `block in process_action'
  activesupport (4.0.0) lib/active_support/callbacks.rb:383:in `_run__408012802371174283__process_action__callbacks'
  activesupport (4.0.0) lib/active_support/callbacks.rb:80:in `run_callbacks'
  actionpack (4.0.0) lib/abstract_controller/callbacks.rb:17:in `process_action'
  actionpack (4.0.0) lib/action_controller/metal/rescue.rb:29:in `process_action'
  actionpack (4.0.0) lib/action_controller/metal/instrumentation.rb:31:in `block in process_action'
  activesupport (4.0.0) lib/active_support/notifications.rb:159:in `block in instrument'
  activesupport (4.0.0) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
  activesupport (4.0.0) lib/active_support/notifications.rb:159:in `instrument'
  actionpack (4.0.0) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
  actionpack (4.0.0) lib/action_controller/metal/params_wrapper.rb:245:in `process_action'
  activerecord (4.0.0) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
  actionpack (4.0.0) lib/abstract_controller/base.rb:136:in `process'
  actionpack (4.0.0) lib/abstract_controller/rendering.rb:44:in `process'
  actionpack (4.0.0) lib/action_controller/metal.rb:195:in `dispatch'
  actionpack (4.0.0) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'
  actionpack (4.0.0) lib/action_controller/metal.rb:231:in `block in action'
  actionpack (4.0.0) lib/action_dispatch/routing/route_set.rb:80:in `dispatch'
  actionpack (4.0.0) lib/action_dispatch/routing/route_set.rb:48:in `call'
  actionpack (4.0.0) lib/action_dispatch/journey/router.rb:71:in `block in call'
  actionpack (4.0.0) lib/action_dispatch/journey/router.rb:59:in `call'
  actionpack (4.0.0) lib/action_dispatch/routing/route_set.rb:655:in `call'
  apipie-rails (0.0.22) lib/apipie/static_dispatcher.rb:56:in `call'
  rack (1.5.2) lib/rack/etag.rb:23:in `call'
  rack (1.5.2) lib/rack/conditionalget.rb:25:in `call'
  rack (1.5.2) lib/rack/head.rb:11:in `call'
  actionpack (4.0.0) lib/action_dispatch/middleware/params_parser.rb:27:in `call'
  actionpack (4.0.0) lib/action_dispatch/middleware/flash.rb:241:in `call'
  rack (1.5.2) lib/rack/session/abstract/id.rb:225:in `context'
  rack (1.5.2) lib/rack/session/abstract/id.rb:220:in `call'
  actionpack (4.0.0) lib/action_dispatch/middleware/cookies.rb:486:in `call'
  activerecord (4.0.0) lib/active_record/query_cache.rb:36:in `call'
  activerecord (4.0.0) lib/active_record/connection_adapters/abstract/connection_pool.rb:626:in `call'
  activerecord (4.0.0) lib/active_record/migration.rb:369:in `call'
  actionpack (4.0.0) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
  activesupport (4.0.0) lib/active_support/callbacks.rb:373:in `_run__980017763409925121__call__callbacks'
  activesupport (4.0.0) lib/active_support/callbacks.rb:80:in `run_callbacks'
  actionpack (4.0.0) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
  actionpack (4.0.0) lib/action_dispatch/middleware/reloader.rb:64:in `call'
  actionpack (4.0.0) lib/action_dispatch/middleware/remote_ip.rb:76:in `call'
  better_errors (0.9.0) lib/better_errors/middleware.rb:84:in `protected_app_call'
  better_errors (0.9.0) lib/better_errors/middleware.rb:79:in `better_errors_call'
  better_errors (0.9.0) lib/better_errors/middleware.rb:56:in `call'
  actionpack (4.0.0) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
  actionpack (4.0.0) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
  railties (4.0.0) lib/rails/rack/logger.rb:38:in `call_app'
  railties (4.0.0) lib/rails/rack/logger.rb:21:in `block in call'
  activesupport (4.0.0) lib/active_support/tagged_logging.rb:67:in `block in tagged'
  activesupport (4.0.0) lib/active_support/tagged_logging.rb:25:in `tagged'
  activesupport (4.0.0) lib/active_support/tagged_logging.rb:67:in `tagged'
  railties (4.0.0) lib/rails/rack/logger.rb:21:in `call'
  actionpack (4.0.0) lib/action_dispatch/middleware/request_id.rb:21:in `call'
  rack (1.5.2) lib/rack/methodoverride.rb:21:in `call'
  rack (1.5.2) lib/rack/runtime.rb:17:in `call'
  activesupport (4.0.0) lib/active_support/cache/strategy/local_cache.rb:83:in `call'
  rack (1.5.2) lib/rack/lock.rb:17:in `call'
  actionpack (4.0.0) lib/action_dispatch/middleware/static.rb:64:in `call'
  railties (4.0.0) lib/rails/engine.rb:511:in `call'
  railties (4.0.0) lib/rails/application.rb:97:in `call'
  rack (1.5.2) lib/rack/content_length.rb:14:in `call'
  puma (2.5.1) lib/puma/server.rb:472:in `handle_request'
  puma (2.5.1) lib/puma/server.rb:343:in `process_client'
  puma (2.5.1) lib/puma/server.rb:242:in `block in run'
  puma (2.5.1) lib/puma/thread_pool.rb:92:in `block in spawn_thread'

4voto

chrishough Points 1059

Bien que je continue à penser qu'il s'agit d'un bogue dans l'enregistrement actif, j'ai pu le contourner avec la fonction https://github.com/rails-api/active_model_serializers gem. La surcharge de to_json par cette gemme a éliminé le besoin d'appeler le code du bogue dans l'enregistrement actif.

Quelqu'un d'autre a une meilleure réponse ?

Contrôleur mis à jour :

class V1::DealsController < ApplicationController

    def by_mall_id
      deals = Deal.where(mallid: params[:id]).first
      render json: deals, serializer: V1::DealSerializer
    end

end

Mon nouveau DealSerializer :

class V1::DealSerializer < ActiveModel::Serializer
    attributes :MALLID

    def MALLID
      object.mallid
    end

end

2voto

Ricardo Rivas Points 610

C'est parce que votre table n'a pas de fonction clé_primaire . Vous pouvez exécuter une migration comme ceci : (ceci est rails 5 cependant)

class AddFieldToPosaCode < ActiveRecord::Migration[5.0]
  execute 'ALTER TABLE my_table ADD PRIMARY KEY(my_column)'
end

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X