Skip to content

Commit

Permalink
Remove camelize from core extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
shioyama committed Jul 30, 2017
1 parent 17ae360 commit d012b32
Show file tree
Hide file tree
Showing 10 changed files with 75 additions and 16 deletions.
2 changes: 1 addition & 1 deletion lib/mobility.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ module Mobility
autoload :FallthroughAccessors, "mobility/fallthrough_accessors"
autoload :LocaleAccessors, "mobility/locale_accessors"
autoload :Translates, "mobility/translates"
autoload :Util, "mobility/util"
autoload :Wrapper, "mobility/wrapper"

require "mobility/orm"
Expand Down Expand Up @@ -68,7 +69,6 @@ class VersionNotSupportedError < ArgumentError; end
require "sequel"
raise VersionNotSupportedError, "Mobility is only compatible with Sequel 4.0 and greater" if ::Sequel::MAJOR < 4
require "sequel/plugins/mobility"
require "sequel/extensions/inflector"
require "sequel/plugins/dirty"
autoload :Sequel, "mobility/sequel"
Loaded::Sequel = true
Expand Down
4 changes: 3 additions & 1 deletion lib/mobility/attributes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ def title_ja=(value)
=end
class Attributes < Module
include Util

# Method (accessor, reader or writer)
# @return [Symbol] method
attr_reader :method
Expand Down Expand Up @@ -197,7 +199,7 @@ def define_writer(attribute)
end

def get_backend_class(backend: nil, model_class: nil)
klass = Module === backend ? backend : Mobility::Backend.const_get(backend.to_s.camelize.gsub(/\s+/, ''.freeze).freeze)
klass = Module === backend ? backend : Mobility::Backend.const_get(camelize(backend).gsub(/\s+/, ''.freeze).freeze)
klass.for(model_class)
end
end
Expand Down
3 changes: 2 additions & 1 deletion lib/mobility/backend/sequel/key_value.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module Backend
class Sequel::KeyValue
include Sequel
include KeyValue
include Util

require 'mobility/backend/sequel/key_value/query_methods'

Expand Down Expand Up @@ -125,7 +126,7 @@ def translation_for(locale, _options = {})
def save_translations
cache.each_value do |translation|
next unless translation.value.present?
translation.id ? translation.save : model.send("add_#{association_name.to_s.singularize}", translation)
translation.id ? translation.save : model.send("add_#{singularize(association_name)}", translation)
end
end

Expand Down
9 changes: 5 additions & 4 deletions lib/mobility/backend/sequel/table.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module Backend
class Sequel::Table
include Sequel
include Table
include Util

require 'mobility/backend/sequel/table/query_methods'

Expand Down Expand Up @@ -45,10 +46,10 @@ def write(locale, value, **options)
def self.configure(options)
raise CacheRequired, "Cache required for Sequel::Table backend" if options[:cache] == false
table_name = options[:model_class].table_name
options[:table_name] ||= :"#{table_name.to_s.singularize}_translations"
options[:foreign_key] ||= table_name.to_s.downcase.singularize.camelize.foreign_key
options[:table_name] ||= :"#{singularize(table_name)}_translations"
options[:foreign_key] ||= foreign_key(camelize(singularize(table_name.to_s.downcase)))
if (association_name = options[:association_name]).present?
options[:subclass_name] ||= association_name.to_s.singularize.camelize
options[:subclass_name] ||= camelize(singularize(association_name))
else
options[:association_name] = :model_translations
options[:subclass_name] ||= :Translation
Expand Down Expand Up @@ -87,7 +88,7 @@ def self.configure(options)
super()
cache_accessor = instance_variable_get(:"@__mobility_#{association_name}_cache")
cache_accessor.each_value do |translation|
translation.id ? translation.save : send("add_#{association_name.to_s.singularize}", translation)
translation.id ? translation.save : send("add_#{Mobility::Util.singularize(association_name)}", translation)
end if cache_accessor
end
end
Expand Down
5 changes: 0 additions & 5 deletions lib/mobility/core_ext/string.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@
=end
class String
# paraphrased from activesupport
def camelize
sub(/^[a-z\d]*/) { $&.capitalize }.gsub(/(?:_|(\/))([a-z\d]*)/) { "#{$1}#{$2.capitalize}" }.gsub('/'.freeze, '::'.freeze)
end

def present?
!blank?
end
Expand Down
59 changes: 59 additions & 0 deletions lib/mobility/util.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
require "singleton"

module Mobility
module Util
VALID_CONSTANT_NAME_REGEXP = /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/.freeze

def self.included(klass)
klass.extend(self)
end

# Converts strings to UpperCamelCase.
# @param [String] str
# @return [String]
def camelize(str)
str.to_s.sub(/^[a-z\d]*/) { $&.capitalize }.gsub(/(?:_|(\/))([a-z\d]*)/) { "#{$1}#{$2.capitalize}" }.gsub('/'.freeze, '::'.freeze)
end

# Tries to find a constant with the name specified in the argument string.
# @param [String] str
# @return [Object]
def constantize(str)
str = str.to_s
raise(NameError, "#{s.inspect} is not a valid constant name!") unless m = VALID_CONSTANT_NAME_REGEXP.match(str)
Object.module_eval("::#{m[1]}", __FILE__, __LINE__)
end

# Returns the singular form of a word in a string.
# @param [String] str
# @return [String]
# @note Simply strips the trailing 's' from a string.
def singularize(str)
str.to_s.gsub(/s$/, '')
end

# Removes the module part from the expression in the string.
# @param [String] str
# @return [String]
def demodulize(str)
str.to_s.gsub(/^.*::/, '')
end

# Creates a foreign key name from a class name
# @param [String] str
# @return [String]
def foreign_key(str)
"#{underscore(demodulize(str))}_id"
end

# Makes an underscored, lowercase form from the expression in the string.
# @param [String] str
# @return [String]
def underscore(str)
str.to_s.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
gsub(/([a-z\d])([A-Z])/,'\1_\2').tr("-", "_").downcase
end

extend self
end
end
1 change: 1 addition & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@

RSpec.configure do |config|
config.include Helpers
config.include Mobility::Util

config.filter_run focus: true
config.run_all_when_everything_filtered = true
Expand Down
4 changes: 2 additions & 2 deletions spec/support/shared_examples/accessor_examples.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Basic test of translated attribute accessors which can be applied to any
# backend, and (since there is no ORM-specific code here) to any ORM.
shared_examples_for "model with translated attribute accessors" do |model_class_name, attribute1=:title, attribute2=:content, **options|
let(:model_class) { model_class_name.constantize }
let(:model_class) { constantize(model_class_name) }
let(:instance) { model_class.new }

it "gets and sets translations in one locale" do
Expand Down Expand Up @@ -96,7 +96,7 @@
end

shared_examples_for "Sequel model with translated attribute accessors" do |model_class_name, attribute1=:title, attribute2=:content, **options|
let(:model_class) { model_class_name.constantize }
let(:model_class) { constantize(model_class_name) }

it "marks model as modified if translation(s) change" do
instance = model_class.create(attribute1 => "foo")
Expand Down
2 changes: 1 addition & 1 deletion spec/support/shared_examples/querying_examples.rb
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@
end

shared_examples_for "Sequel Model with translated dataset" do |model_class_name, attribute1=:title, attribute2=:content|
let(:model_class) { model_class_name.constantize }
let(:model_class) { constantize(model_class_name) }
let(:table_name) { model_class.table_name }
let(:query_scope) { model_class.i18n }

Expand Down
2 changes: 1 addition & 1 deletion spec/support/shared_examples/serialization_examples.rb
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@
shared_examples_for "Sequel Model with serialized translations" do |model_class_name, attribute1=:title, attribute2=:content|
include Helpers

let(:model_class) { model_class_name.constantize }
let(:model_class) { constantize(model_class_name) }
let(:format) { model_class.mobility.modules.first.options[:format] }
let(:backend) { instance.mobility_backend_for(attribute1) }

Expand Down

0 comments on commit d012b32

Please sign in to comment.