diff --git a/lib/mobility/arel/nodes/mysql_ops.rb b/lib/mobility/arel/nodes/mysql_ops.rb new file mode 100644 index 000000000..81a56b581 --- /dev/null +++ b/lib/mobility/arel/nodes/mysql_ops.rb @@ -0,0 +1,50 @@ +# frozen-string-literal: true +require "mobility/arel" + +module Mobility + module Arel + module Nodes + %w[ + JsonDashArrow + JsonDashDoubleArrow + ].each do |name| + const_set name, (Class.new(Binary) do + include ::Arel::Expressions + include ::Arel::Predications + include ::Arel::OrderPredications + include ::Arel::AliasPredication + + def lower + super self + end + end) + end + + class Json < JsonDashDoubleArrow; end + + class JsonContainer < Json + def initialize column, locale, attr + super(Arel::Nodes::JsonDashArrow.new(column, locale), attr) + end + end + end + + module Visitors + def visit_Mobility_Arel_Nodes_JsonDashArrow o, a + json_infix o, a, '->' + end + + def visit_Mobility_Arel_Nodes_JsonDashDoubleArrow o, a + json_infix o, a, '->>' + end + + private + + def json_infix o, a, opr + visit(Nodes::Grouping.new(::Arel::Nodes::InfixOperation.new(opr, o.left, o.right)), a) + end + end + + ::Arel::Visitors::MySQL.include Visitors + end +end diff --git a/lib/mobility/backends/active_record/json.rb b/lib/mobility/backends/active_record/json.rb index bb4e29bd8..738d3214a 100644 --- a/lib/mobility/backends/active_record/json.rb +++ b/lib/mobility/backends/active_record/json.rb @@ -1,5 +1,6 @@ require 'mobility/backends/active_record/pg_hash' -require 'mobility/arel/nodes/pg_ops' +#require 'mobility/arel/nodes/pg_ops' +require 'mobility/arel/nodes/mysql_ops' module Mobility module Backends @@ -36,7 +37,7 @@ class Json < PgHash # attribute key on jsonb column def self.build_node(attr, locale) column_name = column_affix % attr - Arel::Nodes::Json.new(model_class.arel_table[column_name], build_quoted(locale)) + Arel::Nodes::Json.new(model_class.arel_table[column_name], build_quoted("$.\"#{locale}\"")) end end end diff --git a/spec/active_record/schema.rb b/spec/active_record/schema.rb index 584850c53..db745e25a 100644 --- a/spec/active_record/schema.rb +++ b/spec/active_record/schema.rb @@ -92,6 +92,15 @@ def up t.timestamps null: false end + if ENV['DB'] == 'mysql' + create_table "json_posts" do |t| + t.json :my_title_i18n + t.json :my_content_i18n + t.boolean :published + t.timestamps null: false + end + end + if ENV['DB'] == 'postgres' create_table "jsonb_posts" do |t| t.jsonb :my_title_i18n, default: {} diff --git a/spec/mobility/backends/active_record/json_spec.rb b/spec/mobility/backends/active_record/json_spec.rb index a0ba10e9a..2e1cf6757 100644 --- a/spec/mobility/backends/active_record/json_spec.rb +++ b/spec/mobility/backends/active_record/json_spec.rb @@ -1,6 +1,6 @@ require "spec_helper" -describe "Mobility::Backends::ActiveRecord::Json", orm: :active_record, db: :postgres do +describe "Mobility::Backends::ActiveRecord::Json", orm: :active_record do require "mobility/backends/active_record/json" extend Helpers::ActiveRecord before do diff --git a/spec/support/shared_examples/querying_examples.rb b/spec/support/shared_examples/querying_examples.rb index 11cc1ac46..77eacb62f 100644 --- a/spec/support/shared_examples/querying_examples.rb +++ b/spec/support/shared_examples/querying_examples.rb @@ -443,14 +443,16 @@ def query(*args, &block); model_class.i18n(*args, &block); end end describe "LIKE/ILIKE (matches)" do - it "includes partial string matches" do - foobar = model_class.create(a1 => "foObar") - barfoo = model_class.create(a1 => "barfOo") - expect(query { __send__(a1).matches("foo%") }).to match_array([i[0], *i[5..6], foobar]) - expect(query { __send__(a1).matches("%foo") }).to match_array([i[0], *i[5..6], barfoo]) + if ENV['DB'] != 'mysql' + it "includes partial string matches" do + foobar = model_class.create(a1 => "foObar") + barfoo = model_class.create(a1 => "barfOo") + expect(query { __send__(a1).matches("foo%") }).to match_array([i[0], *i[5..6], foobar]) + expect(query { __send__(a1).matches("%foo") }).to match_array([i[0], *i[5..6], barfoo]) + end end - if ENV['DB'] == 'postgres' && ::ActiveRecord::VERSION::STRING >= '5.0' + if (ENV['DB'] == 'mysql' || ENV['DB'] == 'postgres') && ::ActiveRecord::VERSION::STRING >= '5.0' it "works with case_sensitive option" do foobar = model_class.create(a1 => "foObar") barfoo = model_class.create(a1 => "barfOo")