Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rails on Two DBs

yui-knk
November 08, 2015

Rails on Two DBs

yui-knk

November 08, 2015
Tweet

More Decks by yui-knk

Other Decks in Programming

Transcript

  1. ࢲͱ"TBLVTBSC w େߐށ3VCZձٞࢀՃ   w ॳࢀՃ͸z"TBLVTBSCճه೦͓ॕ͍ձz   w

    ݄ʹճ͘Β͍ࢀՃ w 3BJMTͷ͜ͱͱ͔ɺ3VCZͷ͜ͱͱ͔ΛDPNNJUFS ͷਓʹ૬ஊ
  2. w 6TFST w 3FMBUJPOTIJQT w .JDSPQPTUT w ʜ w 6TFST

    w 3FMBUJPOTIJQT w 'FFET w ʜ mysql> show databases; +-----------------------------+ | Database | +-----------------------------+ | service1_development | | service2_development | | service1_test | | service2_test | +-----------------------------+ 2 rows in set (0.00 sec) 4FSWJDF 4FSWJDF
  3. BDUJWFSFDPSEUFTUDBTFT NVMUJQMF@EC@UFTUSC w Ұݟɺ-(5.ʹΈ͑Δ͡Όͳ͍Ͱ͔͢ def test_associations c1 = Course.find(1) assert_equal

    2, c1.entrants.count e1 = Entrant.find(1) assert_equal e1.course.id, c1.id c2 = Course.find(2) assert_equal 1, c2.entrants.count e3 = Entrant.find(3) assert_equal e3.course.id, c2.id end
  4. ෳࡶͳ"TTPDJBUJPO # OK SELECT `teachers`.* FROM `teachers` INNER JOIN `college_teachers`

    ON `teachers`.`id` = `college_teachers`.`teacher_id` WHERE `college_teachers`.`college_id` = 1 # NG SELECT `colleges`.* FROM `colleges` INNER JOIN `college_teachers` ON `colleges`.`id` = `college_teachers`.`college_id` WHERE `college_teachers`.`teacher_id` = 1 # OK college.teachers # NG teacher.colleges
  5. ෳࡶͳ"TTPDJBUJPO # OK SELECT `teachers`.* FROM `teachers` INNER JOIN `college_teachers`

    ON `teachers`.`id` = `college_teachers`.`teacher_id` WHERE `college_teachers`.`college_id` = 1 # NG SELECT `colleges`.* FROM `colleges` INNER JOIN `college_teachers` ON `colleges`.`id` = `college_teachers`.`college_id` WHERE `college_teachers`.`teacher_id` = 1 # OK college.teachers # NG teacher.colleges
  6. EBUBCBTF໊Λ ΫΤϦʹؚΊΔ # BEFORE SELECT `colleges`.* FROM `colleges` INNER JOIN

    `college_teachers` ON `colleges`.`id` = `college_teachers`.`college_id` WHERE `college_teachers`.`teacher_id` = 1 # AFTER SELECT `database2`.`colleges`.* FROM `database2`.`colleges` INNER JOIN `database1`.`college_teachers` ON `database1`.`colleges`.`id` = `database1`.`college_teachers`.`college_id` WHERE `database1`.`college_teachers`.`teacher_id` = 1
  7. --- a/lib/arel/table.rb +++ b/lib/arel/table.rb @@ -6,7 +6,7 @@ module Arel

    @engine = nil class << self; attr_accessor :engine; end - attr_accessor :name, :engine, :aliases, :table_alias + attr_accessor :name, :engine, :aliases, :table_alias, :database_name @@ -18,6 +18,7 @@ module Arel @aliases = [] @table_alias = nil @primary_key = nil + @database_name = nil --- a/lib/arel/visitors/to_sql.rb +++ b/lib/arel/visitors/to_sql.rb @@ -612,6 +612,7 @@ module Arel end def visit_Arel_Table o, collector + collector << "#{quote_table_name o.database_name}." if o.database_name if o.table_alias collector << "#{quote_table_name o.name} #{quote_table_name o.table_alias}" else
  8. --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -235,7 +235,9 @@ module ActiveRecord

    # scope :published_and_commented, -> { published.and(self.arel_table[:comments_count].gt(0)) } # end def arel_table # :nodoc: - @arel_table ||= Arel::Table.new(table_name, arel_engine) + @arel_table ||= Arel::Table.new(table_name, arel_engine).tap {|a| + a.database_name = connection.instance_variable_get(:@config)[:database] if connection.instance_variable_get(:@config) + } end --- a/Gemfile +++ b/Gemfile @@ -124,3 +125,5 @@ end # A gem necessary for ActiveRecord tests with IBM DB gem 'ibm_db' if ENV['IBM_DB'] + +gem 'arel', github: 'yui-knk/arel', branch: 'feature/database_name'
  9. 3BJMTͷςετ͕͚͜Δ ActiveRecord::ConnectionAdapters::Mysql2SchemaTest#test_schema: ActiveRecord::StatementInvalid: Mysql2::Error: You have an error in your

    SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.`posts` ORDER BY `activerecord_unittest`.`posts`.`id` ASC LIMIT 1’ at line 1: SELECT `activerecord_unittest`.`posts`.* FROM `activerecord_unittest`.`activerecord_unittest`.`posts` ORDER BY `activerecord_unittest`.`posts`.`id` ASC LIMIT 1 ... ruby/rails/activerecord/test/cases/adapters/mysql2/schema_test.rb:23:in `test_schema'
  10. UFTUDBTFTBEBQUFST NZTRMTDIFNB@UFTUSC def setup @connection = ActiveRecord::Base.connection db = Post.connection_pool.spec.config[:database]

    table = Post.table_name @db_name = db @omgpost = Class.new(ActiveRecord::Base) do self.table_name = "#{db}.#{table}" def self.name; 'Post'; end end end def test_schema assert @omgpost.first end
  11. "3UBCMF@OBNF class College < ActiveRecord::Base self.table_name = "database2.colleges" end class

    CollegeTeacher < ActiveRecord::Base self.table_name = "database1.college_teachers" end class Teacher < ActiveRecord::Base self.table_name = "database1.teachers" end
  12. ""4. class User < ActiveRecord::Base include AASM aasm column: :status

    do state :sleeping #... end end User.sleeping # => "SELECT `database1`.`users`.* FROM `database1`.`users` WHERE `database1`.`users.status` = 'sleeping'"
  13. ""4. conditions = {"#{@klass.table_name}.#{@klass.aasm(@name).attribute_name}" => name.to_s} if ActiveRecord::VERSION::MAJOR >= 3

    @klass.class_eval do scope name, lambda { where(conditions) } end else @klass.class_eval do named_scope name, :conditions => conditions end end
  14. .JHSBUJPO w ։ൃ EFWFMPQ ͱςετ UFTU Ͱ͸6TFSTςʔϒϧͷ .JHSBUJPOϑΝΠϧ͕΄͍͠ w SJEHFQPMFHFNͰEVNQͯࠩ͠෼ΛͱΔ

    w 6TFST w 3FMBUJPOTIJQT w .JDSPQPTUT w ʜ w 6TFST w 3FMBUJPOTIJQT w 'FFET w ʜ 4FSWJDF 3FQPTJUPSZ 4FSWJDF 3FQPTJUPSZ
  15. .JHSBUJPO # In Repository1 bundle exec ridgepole -c config/database.yml --export

    --split --output schemas/ Schemafile # In Repository2 bundle exec ridgepole -c config/database.yml --export --split --output schemas/ Schemafile # In Repository2 bundle exec ridgepole -c config/database.yml --diff schemas/users.schema ../ repository1/schemas/users.schema #add_column("users", "name", :string, {:after=>"id", :limit=>255}) # ALTER TABLE `users` ADD `name` varchar(255) AFTER `id`