Question

Rails 3.1, Ruby 1.9.2, en utilisant une base de données SQL Server 2008 via le gemme activeRecord-SqlServer-Adapter. Je travaille avec une base de données héritée, donc ce n'était pas volontaire.

Je rencontre un problème étrange avec Activeadmin. Je n'ai pas utilisé activeadmin auparavant et je l'ai ajouté après avoir regardé un railscast. A suivi les instructions d'installation standard et je suis en mesure de me connecter à la console d'administration.

Quand j'ajoute un modèle:

rails generate active_admin:resource Payment

Le modèle (en pluriel) est désormais visible sur le tableau de bord ActiveAdmin. Cependant, lorsque je clique sur le lien, j'obtiens l'erreur suivante:

TinyTds::Error: No column name was specified for column 2 of '__rnt'.: EXEC 
sp_executesql N'SELECT TOP (1) [__rnt].* FROM ( SELECT ROW_NUMBER() OVER (ORDER
BY [Payments].[UPaymentID] ASC) AS [__rn], 1 FROM [Payments] ) AS [__rnt] 
WHERE [__rnt].[__rn] > (0) ORDER BY [__rnt].[__rn] ASC'

Maintenant, cette requête renvoie la même erreur si je l'exécute directement sur la base de données SQL Server - elle n'aime pas la colonne sans nom de "1".

A commencé à creuser pour voir quel était le problème. Les endroits évidents à regarder seraient dans les transitions entre ActiveAlmin et ActiveRecord, puis ActiveRecord et l'adaptateur SQL Server. Voici la trace de pile pour la première intersection:

activerecord (3.1.0) lib/active_record/relation/finder_methods.rb:197:in `exists?'  
activeadmin (0.4.2) lib/active_admin/views/pages/index.rb:41:in `items_in_collection?'  
activeadmin (0.4.2) lib/active_admin/views/pages/index.rb:20:in `main_content'

Cela ressemble à des éléments_in_collection? Est-ce que l'appel existe? sur une collection qui a fait retirer les filtres de commande. À ce stade, nous remettons à ActiveRecord. Si nous regardons la transition de ActiveRecord à l'adaptateur SQL Server, il semble que l'instruction SELECT ait déjà été formée:

activerecord-sqlserver-adapter (3.1.6) lib/active_record/connection_adapters/sqlserver/database_statements.rb:348:in `do_exec_query'
activerecord-sqlserver-adapter (3.1.6) lib/active_record/connection_adapters/sqlserver/database_statements.rb:24:in `exec_query'
activerecord-sqlserver-adapter (3.1.6) lib/active_record/connection_adapters/sqlserver/database_statements.rb:297:in `select'
activerecord (3.1.0) lib/active_record/connection_adapters/abstract/database_statements.rb:18:in `select_all'
activerecord (3.1.0) lib/active_record/connection_adapters/abstract/query_cache.rb:61:in `block in select_all'

Je suis totalement confus quant à la raison pour laquelle le SQL serait généré comme il est. Il y a quelques problèmes candidats:

  1. Je travaille sur une base de données héritée avec un schéma impair. Je dois définir des noms de table et des noms de clés principaux dans mes modèles. je ne sais pas pense C'est le problème, car la requête qui sort semble utiliser la clé primaire et les noms de table appropriés.
  2. Problèmes avec le activerecord-sqlserver-adapter gemme. Cependant, j'ai tiré le code source, et il ne semble pas qu'il y ait quelque chose qui assemblera cette requête de cette façon.

Quelqu'un a-t-il rencontré quelque chose de similaire à cela? Il se peut que je devrai simplement déboguer dans toute la pile pour voir ce qui se passe. Pensé qu'il vaut la peine de vérifier ici d'abord.

EDIT: Je suis maintenant assez sûr que c'est un bug dans ActiveRecord-SqlServer-Adapter. Publiera une résolution ici une fois que je l'aurai.

EDIT2: Peut reproduire l'erreur sans activeadmin du tout. Ceci est lié à la façon dont l'adaptateur SQL Server traite des requêtes de décalage. Appel

MyModel.offset(1).exists?

produit la même erreur. J'ai un patch laid à l'adaptateur qui passe tous les tests unitaires, mais je vais essayer de trouver une solution plus élégante avant de faire une demande de traction.

Était-ce utile?

La solution

Je ne suis pas sûr que ce soit exactement la réponse, mais j'ai corrigé mon code local et votre requête fonctionne pour moi maintenant.

Tout d'abord, le problème de GitHub:

https://github.com/rails/rails/issues/1623

Et puis la demande de traction pour le correctif d'Arkadiyk:

https://github.com/arkadiyk/rails/commit/7e2ddddb303d17adc825ebb691097a93902fa539

Le problème de base est Finder_methods.rb, qui a le code existant autour de la ligne 187 ou 188:

relation = relation.except(:select).select("1").limit(1)

MSSQL BARFS sur la colonne sans nom que cela génère, donc le code suivant le corrige:

relation = relation.except(:select).select("1 as o").limit(1)

J'espère que cela pourra aider.

Autres conseils

Il semble y avoir deux alternatives pour réparer ceci: le réparer en rails, ou le réparer dans ActiveRecord-SqlServer-Adapter.

Le lien que Raels a fourni est probablement le bon moyen de résoudre ce problème, cependant, la demande de traction n'a pas été acceptée dans les rails. Je m'inquiète d'utiliser une version patchée de rails, car cela me forcera à rester avec ma version corrigée, ou continuer à patcher à mesure que les rails évoluent.

Al Alternative consiste à résoudre ce problème dans ActiveRecord-SqlServer-Adapter. J'ai soumis une demande de traction ici:

https://github.com/rails-sqlserver/activerrecord-sqlserver-adapter/pull/171

Il est possible que le mainteneur d'Active-SqlServer-Adapter proposerait une solution plus élégante. S'il le fait, je mettrai à jour cette réponse.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top