Rails on Two DBs

B3ba3ccedfbf4d605f00bafd1a732529?s=47 yui-knk
November 08, 2015

Rails on Two DBs

B3ba3ccedfbf4d605f00bafd1a732529?s=128

yui-knk

November 08, 2015
Tweet

Transcript

  1. 3BJMTPO5XP%#T :VJDIJSP,BOFLP େߐށ3VCZձٞ

  2. 8IP*BN ,BOFLP:VJDIJSP !ZVJLOL

  3. ZVJLOL (JU)VC TQJLFPMBG UXJUUFS  EPDSBJMTSBJMTHVJEFTKQ QSZBDUJWF@EFDPSBUPS ΋ͱܦཧϚϯ

  4. 3BJMTΨΠυ຋༁νʔϜ

  5. &EHF3BJMT

  6. IUUQTTQFBLFSEFDLDPNB@NBUTVEBSBJMTLBJGBGBMTFIJNJUV

  7. <DJTLJQ>

  8. None
  9. &EHF3BJMT $PNNJUFS

  10. &EHF3BJMT $PNNJUFS

  11. &EHF3BJMT $PNNJUFS ೔ຊਓͬΆ͍ਓ

  12. IUUQZZBHJIBUFOBCMPHDPN

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

    ݄ʹճ͘Β͍ࢀՃ w 3BJMTͷ͜ͱͱ͔ɺ3VCZͷ͜ͱͱ͔ΛDPNNJUFS ͷਓʹ૬ஊ
  14. 3VCZʹݶΒͣɺ࿩ऀ͕ݱ ࡏڵຯͷ͋Δ໘ന͍಺༰

  15. ໘ന͍ͱ͸

  16. 3BJMTͱෳ਺%#

  17. ෳ਺%#ͱ͸

  18. ෳ਺%# w %#෼ׂʁ w 38TQMJUUJOH  w γϟʔσΟϯάʁ IUUQTTQFBLFSEFDLDPNFBHMFUNUGVTIVECUPSBJMT

  19. 38TQMJUUJOH TXJUDI@QPJOU

  20. γϟʔσΟϯά NJYFE@HBVHF

  21. 0DUPQVT ஌Βͳ͍ࢠͰ͢Ͷ

  22. ΧδϡΞϧͳ%#෼ׂ w ࠓճ͸ෛՙ෼ࢄ͕໨తͰ͸ͳ͘ w ͋ΔαʔϏεͷಛఆͷ5BCMF 6TFST ΛଞͷαʔϏ εͰ΋࢖͍͍ͨ w 3BJMT.Z42-

  23. 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
  24. IUUQTHJUIVCDPNSBJMTSBJMTUSFF WBDUJWFSFDPSEUFTUDBTFT NVMUJQMF@EC@UFTUSC

  25. ʜ ݁ߏੲ͔Β͋Δ

  26. 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
  27. ෳࡶͳ"TTPDJBUJPO w 5FBDIFST w $PMMFHF5FBDIFST w $PMMFHFT %BUBCBTF %BUBCBTF $PMMFHF5FBDIFS

    $PMMFHF 5FBDIFS / / 
  28. ෳࡶͳ"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
  29. ෳࡶͳ"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
  30. DPMMFHFUFBDIFST $PMMFHF5FBDIFS $PMMFHF 5FBDIFS / /  +0*/Մೳ

  31. UFBDIFSDPMMFHFT $PMMFHF5FBDIFS $PMMFHF 5FBDIFS / /  +0*/ ෆ Մೳ

  32. 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
  33. "SFMΛ֦ுͩ

  34. --- 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
  35. --- 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'
  36. 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'
  37. 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
  38. "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
  39. 1SPCMFNT w (FN ""4. ͷΫΤϦ w .JHSBUJPO w 3BJMTଆͷαϙʔτ

  40. ""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'"
  41. ""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
  42. 3BJMT ͓޷ΈͰ͸ͳ͍༷ࢠ

  43. .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
  44. .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`
  45. αϙʔτͱ͸

  46. 3BJMTͷαϙʔτ

  47. 3BJMTͷαϙʔτ յΕͨ

  48. 3BJMTͷαϙʔτ ઌिؾ͕͍ͭͨ

  49. 3BJMTͷαϙʔτ ܧଓ৹ٞத

  50. ݁ߏલ͔Βͩͬͨɻɻɻ

  51. ·ͱΊ w 5FTUΛΑΜͰΈΔ w NBTUFSϒϥϯνΛ͞ΘͬͯΈΔ w 3BJMΛෑ͍ͯΈΔ φΠενϟϨϯδ

  52. ·ͱΊ

  53. 5IBOLZPV IUUQTXXXqJDLSDPNQIPUPTUBNCBLP