2012-02-22 24 views
0

Rails 3.1、Ruby 1.9.2、activerecord-sqlserver-adapter gemによるSQL Server 2008データベースの使用。私は従来のデータベースを使っているので、これは自発的ではありませんでした。ActiveAdminクエリ中の列名が見つかりません

ActiveAdminで奇妙な問題が発生しています。以前はActiveAdminを使用していませんでしたが、Railkeastを見てから追加しました。標準のインストール手順に従って、管理コンソールにログインできます。

私がモデルを追加

rails generate active_admin:resource Payment 

モデル(複数では)今ActiveAdminダッシュボード上に表示されています。私はリンクをクリックしたときしかし、私は次のエラーを取得する: - それはの無名列が好きではありません

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' 

さて、このクエリは、私はSQL Serverデータベース上で直接実行する場合は、同じエラーを返します"1"。

問題が何かを確認するために掘削を開始しました。明白な場所はactiveadminとactiverecord、そして次にactiverecordとSQL Serverアダプタの間の移行です。最初の交差点のスタックトレースは次のとおりです。

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' 

items_in_collectionのように見えますか?呼び出しが存在していますか?オーダーフィルターが削除されたコレクションでこの時点で、ActiveRecordに渡します。我々は、SQL ServerのアダプタへのActiveRecordからの移行を見れば、それはSELECTステートメントが既に形成されているかのように見えます:

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' 

私は、SQLの道それは生成される理由として完全に混乱していますです。いくつかの問題候補領域があります:

  1. 私は奇妙なスキーマを持つ従来のデータベースで作業しています。モデル内でテーブル名と主キー名を設定する必要があります。私は出てこない出てくるクエリが適切な主キーとテーブル名を使用しているようだから、これは問題です。
  2. activerecord-sqlserver-adapter gemの問題点しかし、私はソースコードを引っ張りましたが、このような方法でこのクエリを組み立てるようなものはないようです。

誰もこれに似たものに遭遇しましたか?何が起きているのかを知るためには、スタック全体を通して自分のやり方をデバッグする必要があるかもしれません。それは最初にここで確認する価値があると考えていた。

編集:これはactiverecord-sqlserver-adapterのバグです。一度私がそれを持っていればここで解決を投稿します。

Edit2:ActiveAdminを使わずにエラーを再現することができます。これは、SQL Serverアダプタがオフセットクエリを処理する方法に関連しています。

MyModel.offset(1).exists? 

同じエラーが発生します。私はすべての単体テストを渡すアダプターの醜いパッチを持っていますが、プルリクエストを行う前にもっと洗練された解決策を見つけるつもりです。

答えて

1

これは正確にはわかりませんが、私はローカルコードにパッチを当てています。

まず、githubの問題:

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

とarkadiykの修正のために、その後、プルリクエスト:

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

基本的な問題はfinder_methods.rbで、既存のコードを持っています187行目または188行目:

relation = relation.except(:select).select("1").limit(1) 
次のコードは、それを修正するよう

MSSQLは、これが生成する無名列にbarfs:

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

お役に立てば幸いです。

+0

ありがとうございました。私は、これを修正する適切な場所がどこにあるのかについて、混同しています。明らかに、1が選択されている列にエイリアスを付けると、レールが私たちの生活を楽にすることができますが、データベースに固有の問題のほうが多いので、そうする必要はないと思います。私はactiverecord-sqlserver-adapterのパッチを持っていますが、これは同じことを成し遂げますが、もっと醜い方法で行います(選択処理中にノードにアクセスし、ノードが "1"の場合はエイリアス列を追加します)。私は私のプルリクエストに戻ってリンクを返すだけです。 –

+0

合意。また、一時的な列名を作成し、処理の最後にクエリと結果セットからそれらをクリーンアップする一般的なアダプタ機能を見ることができます。これにより、アダプターは、導入された列を管理し、ユーザーが列名に異なるジェネレーターを指定できるようにします。ちょうどアイデア。私は何が最善のものかを見るためにコードを十分に見ていない。 – Raels

0

これを修正するには2つの方法があるようです:レールで修正するか、activerecord-sqlserver-adapterで修正します。

Raelsが提供しているリンクはおそらくこれを修正する正しい方法ですが、プルリクエストはレールに受け入れられていません。私は、パッチされたバージョンのレールを使用することに懸念しています。これにより、パッチされたバージョンに固執するか、またはレールが進化するにつれてパッチを当て続けることになります。

代わりに、これをactiverecord-sqlserver-adapterで修正することもできます。私はここプル要求を提出しました:

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

それはアクティブのSQLServerアダプタのメンテナは、よりエレガントな修正を思い付くすることが可能です。もしそうなら、私はこの答えを更新します。

関連する問題