Rails4の抽象クラス(Model)に定義したscopeが変なSQLを吐く件
railsでは簡単な設定によりテーブルを持たないモデルを作成する事ができます。
複数のモデルに共通する設定やメソッドなどを1箇所に書くことが出来て便利です。
今回はRails4において、scopeを定義した抽象クラスを継承した子クラスでscopeを利用した際に遭遇したエラーについてです。
ちなみに根本的な解決策は見つけていません。
抽象クラスとscopeを定義して(self.abstract_class = true)
SQLが自動生成された際にテーブル名が空になってしまっています。
どうもActiveRecordの問題のようなので簡単には直せそうにありません。
SQLを生成する際に抽象クラスのテーブル名(当然空)を参照してしまっていることが原因?
子クラスでscopeをそれぞれ定義して乗り切っています。DRY(笑)
抽象クラスを使うのを諦めてModuleでスコープを定義して使いまわすのはありかもしれません。
複数のモデルに共通する設定やメソッドなどを1箇所に書くことが出来て便利です。
今回はRails4において、scopeを定義した抽象クラスを継承した子クラスでscopeを利用した際に遭遇したエラーについてです。
ちなみに根本的な解決策は見つけていません。
抽象クラスとscopeを定義して(self.abstract_class = true)
#app/models/abstract_model.rb class AbstractModel < ActiveRecord::Base self.abstract_class = true scope :latest, -> { order("created_at DESC") } end継承してサブクラスを定義
#app/models/foo.rb class Foo < AbstractModel endそしてサブクラスでscopeを利用すると
#app/controllers/foo_controller.rb class FooController < ApplicationController def bar @foos = Foo.latest end end #app/views/foo/bar.html.erb <% @foos.each do |foo| %> <%= foo.name %> <% end %>このようなエラーが
ActionView::Template::Error: Mysql2::Error: Incorrect table name '': SHOW FULL FIELDS FROM ``
SQLが自動生成された際にテーブル名が空になってしまっています。
どうもActiveRecordの問題のようなので簡単には直せそうにありません。
Githubで見つけた関連Issue
Scopes defined on Abstract ActiveRecord classes are missing table names when called from subclasses · Issue #10658 · rails/rails · GitHubSQLを生成する際に抽象クラスのテーブル名(当然空)を参照してしまっていることが原因?
対策
場当たり的な解決策としてscopeを親クラスに記述することを諦めて子クラスでscopeをそれぞれ定義して乗り切っています。DRY(笑)
抽象クラスを使うのを諦めてModuleでスコープを定義して使いまわすのはありかもしれません。