Railsのモデルで共通部分をまとめる方法を教えてください。


Ruby on Railsで開発をしています。IDEはRubyMineを使ってます。

10個以上のモデルの中、3つのモデルだけモデル名を変更する必要があり、  
テーブル名と違って、テーブルとの連携のためモデルには

[code]

    def self.table_name_prefix
      'm_'
    end
    
[/code]

このようなメソッドを持っています。（３つのモデルに対応するテーブルは全部モデル名の前に「m_」をつけているようになっています。）  
同じメソッドを持っているからこれを共通的にまとめて簡単にしたいんです。  
ですが、まだRails初心者なので、どうすればいいかよくわかりません。  
どうすればきれいに取りまとめることができるのか教えていただきたいんです！




ActiveSupport::Concernを使ってみました。  
こんな感じでどうでしょうか？  
User, Item, Orderの3つのクラスがあり、UserとItemはテーブル名に"m_"というprefixが付く設計です。

[code]

    # db/schema.rb
    ActiveRecord::Schema.define(version: 20151230050425) do
    
      create_table "m_items", force: :cascade do |t|
        t.string   "name"
        t.datetime "created_at", null: false
        t.datetime "updated_at", null: false
      end
    
      create_table "m_users", force: :cascade do |t|
        t.string   "name"
        t.datetime "created_at", null: false
        t.datetime "updated_at", null: false
      end
    
      create_table "orders", force: :cascade do |t|
        t.integer  "user_id"
        t.integer  "item_id"
        t.datetime "created_at", null: false
        t.datetime "updated_at", null: false
      end
    
      add_index "orders", ["item_id"], name: "index_orders_on_item_id"
      add_index "orders", ["user_id"], name: "index_orders_on_user_id"
    
    end
    
    # app/models/concerns/master_table_prefix.rb
    module MasterTablePrefix
      extend ActiveSupport::Concern
    
      module ClassMethods
        def table_name_prefix
          'm_'
        end
      end
    end
    
    # app/models/user.rb
    class User < ActiveRecord::Base
      include MasterTablePrefix
    
      has_many :orders
    end
    
    # app/models/item.rb
    class Item < ActiveRecord::Base
      include MasterTablePrefix
    
      has_many :orders
    end
    
    # app/models/order.rb
    class Order < ActiveRecord::Base
      belongs_to :user
      belongs_to :item
    end
    
[/code]

以下は動作確認用のテストコードです。

[code]

    # test/models/order_test.rb
    require 'test_helper'
    
    class OrderTest < ActiveSupport::TestCase
      test "Create order" do
        user = User.create! name: 'Alice'
        item = Item.create! name: 'MacBook'
        order = Order.create! user: user, item: item
    
        assert_equal order, Order.first
      end
    end
    
[/code]

GitHubにもコードをアップしているので参考にしてみてください。

[JunichiIto/module-prefix-sandbox](https://github.com/JunichiIto/module-
prefix-sandbox)




実装の共有はモジュールを使うのが選択肢の一つかと思います。例えば`models/concerns`にモジュールを作り、それをモデルクラスで`extend`するのはどうでしょうか？(特異メソッドの定義になるので、`include`ではなく`extend`になる)

[code]

    -- app/models/concerns/hoge.rb --
    module TblnamePrefix
      def table_name_prefix
        'm_'
      end
    end
    
    -- app/models/hoo.rb --
    require 'hoge'
    class Hoo < ActiveRecord::Base
      extend TblnamePrefix
    end
    
    (irbでの実行例)
    irb(main):003:0> Hoo.table_name_prefix
    => "m_"
    
[/code]

