LoginSignup
7
7

More than 5 years have passed since last update.

[Ruby]ActiveRecordで動的にテーブルを作成する(Rails風味)。

Last updated at Posted at 2017-11-20

はじめに

Railsアプリを作成するまでもないけど、RailsのようにActiveRecordを快適に使いたいと思った時の一案。

全体

model_controller.rb
require "sqlite3"
require "active_record"

Dir[__dir__ + '/model/*.rb'].each(&method(:require))

ActiveRecord::Base.establish_connection(
  :adapter => 'sqlite3',
  :database => __dir__ + '/db/sample.sqlite3'
)

def create_test_table(code)
  table_name = "sample" + code.to_s + "s"
  table_sym = table_name.to_sym

  unless  ActiveRecord::Base.connection.table_exists? table_sym
    ActiveRecord::Base.connection.create_table table_sym do |t|
      t.string :name
      t.float :score
    end
    orm(table_name)
  end
end

private

# tableとmodelを関連付ける
def orm(table_name)
  model_name = table_name.singularize.camelcase
  file = __dir__ + '/model/' + model_name  + ".rb"
  create_class = "class #{model_name} < ActiveRecord::Base; end"
  IO.write(file, create_class)
  model_path = __dir__ + "/model/" + model_name
  require_relative model_path
end

GIST

1:テーブルを作成する。

同じ構造のテーブルを何個も作りたいということを想定しています。
idカラムは自動的に作成されます。
Ruby ハッシュのキーを変数で使いたい

def create_test_table(code)
  table_name = "sample" + code.to_s + "s"
  table_sym = table_name.to_sym

  unless  ActiveRecord::Base.connection.table_exists? table_sym
    ActiveRecord::Base.connection.create_table table_sym do |t|
      t.string :name
      t.float :score
    end
    orm(table_name)
  end
end

2:テーブルとモデルを関連付ける。

先頭でmodelディレクトリ下のファイルを全て読み込むように設定します。
Rubyでディレクトリ内のすべてのファイルをrequireする方法
&演算子と、procと、Object#method について理解しなおす

#Dir[File.dirname(__FILE__) + '/model/*.rb'].each {|file| require file }
Dir[__dir__ + '/model/*.rb'].each(&method(:require))

モデルディレクトリ下にActiveRecord::Baseを継承したモデルclass作成します。
テーブル情報からModelを動的生成する方法 (ActiveRecordの単体利用時)

def orm(table_name)
  model_name = table_name.singularize.camelcase
  file = __dir__ + '/model/' + model_name  + ".rb"
  create_class = "class #{model_name} < ActiveRecord::Base; end"
  IO.write(file, create_class)
  model_path = __dir__ + "/model/" + model_name
  require_relative model_path
end
  model_path = __dir__ + "/model/" + model_name
  require_relative model_path

の部分で、modelディレクトリに新しく追加されたモデルクラスを読み込みます。

使う

基本

main.rb
require_relative 'model_controller.rb'

create_test_table(7500)
puts Sample7500.count  #=> 0
Sample7500.create(name:"qiita",score:56.3)
puts Sample7500.count  #=> 1

モデルの中でメソッド定義したい。

Railsと同じように作成されたモデルファイルの中にメソッドを書き込むだけでOK。

model/Sample7500.rb
class Sample7500 < ActiveRecord::Base
 def self.hello
    puts "Hello from Model!"
 end
end

普通に使える。

Sample7500.hello #=> "Hello from Model!"
7
7
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7