Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use dry-inflector, because Inflecto is no longer maintained #36

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion lib/lurch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

require "uri"

require "inflecto"
require "rack"
require "faraday"
require "typhoeus"
Expand Down
4 changes: 2 additions & 2 deletions lib/lurch/changeset.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class Changeset

def initialize(type, attributes = {})
is_resource = type.is_a?(Resource)
@type = is_resource ? type.type : Inflector.decode_type(type)
@type = is_resource ? type.type : type
@id = is_resource ? type.id : nil
@attributes = attributes
@relationships = {}
Expand All @@ -28,7 +28,7 @@ def inspect
attrs = attrs.concat(attributes.map { |name, value| "#{name}: #{value.inspect}" })
attrs = attrs.concat(relationships.map { |name, value| "#{name}: #{value.inspect}" })
inspection = attrs.join(", ")
"#<#{self.class}[#{Inflector.classify(type)}] #{inspection}>"
"#<#{self.class}[#{type}] #{inspection}>"
end
end
end
2 changes: 1 addition & 1 deletion lib/lurch/collection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def last?
end

def inspect
suffix = @resources.first ? "[#{Inflector.classify(@resources.first.type)}]" : ""
suffix = @resources.first ? "[#{@resources.first.type}]" : ""
inspection = size ? ["size: #{size}"] : []
inspection << ["pages: #{page_count}"] if page_count
"#<#{self.class}#{suffix} #{inspection.join(', ')}>"
Expand Down
29 changes: 17 additions & 12 deletions lib/lurch/inflector.rb
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
# frozen_string_literal: true

require "dry/inflector"

module Lurch
class Inflector
def initialize(inflection_mode, types_mode)
@inflector = Dry::Inflector.new do |inflections|
inflections.plural "people", "people"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this configuration required here? Would we need a way to expose custom pluralization rules to the end-user?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was basically added only to make the tests run. Apparently dry-inflector does pluralize a little different than Inflecto.
Yes, customizing the Inflector seems to be necessary.
However, I think we should also reduce the number of calls to a minimum, because this seems to be a big performance hit (#37) or remove the inflector completely. Both seems to be out of scope for this PR.

end
define_encode_key(inflection_mode)
define_encode_type(types_mode)
end

def self.classify(str)
Inflecto.classify(str)
end

def self.decode_key(key)
Inflecto.underscore(key.to_s).to_sym
def decode_key(key)
inflector.underscore(key.to_s).to_sym
end

def self.decode_type(type)
Inflecto.pluralize(decode_key(type)).to_sym
def decode_type(type)
inflector.pluralize(decode_key(type)).to_sym
end

def define_encode_key(inflection_mode)
case inflection_mode
when :dasherize
define_singleton_method(:encode_key) { |key| Inflecto.dasherize(key.to_s) }
define_singleton_method(:encode_key) { |key| inflector.dasherize(key.to_s) }
when :underscore
define_singleton_method(:encode_key) { |key| Inflecto.underscore(key.to_s) }
define_singleton_method(:encode_key) { |key| inflector.underscore(key.to_s) }
else
raise ArgumentError, "Invalid inflection mode: #{inflection_mode}"
end
Expand All @@ -35,12 +36,12 @@ def define_encode_type(types_mode)
when :pluralize
define_singleton_method(:encode_type) do |type|
key = encode_key(type)
Inflecto.pluralize(key)
inflector.pluralize(key)
end
when :singularize
define_singleton_method(:encode_type) do |type|
key = encode_key(type)
Inflecto.singularize(key)
inflector.singularize(key)
end
else
raise ArgumentError, "Invalid types mode: #{types_mode}"
Expand All @@ -58,5 +59,9 @@ def encode_types(hash)
acc[encode_type(key)] = block_given? ? yield(value) : value
end
end

private

attr_reader :inflector
end
end
22 changes: 12 additions & 10 deletions lib/lurch/query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def params(params)
end

def type(type)
@type = Inflector.decode_type(type)
@type = inflector.decode_type(type)
self
end

Expand All @@ -70,14 +70,14 @@ def find(id)

def save(changeset)
raise ArgumentError, "No type specified for query" if @type.nil?
raise ArgumentError, "Type mismatch" if @type != changeset.type
raise ArgumentError, "Type mismatch" if @type != inflector.decode_type(changeset.type)

@store.save(changeset, to_query)
end

def insert(changeset)
raise ArgumentError, "No type specified for query" if @type.nil?
raise ArgumentError, "Type mismatch" if @type != changeset.type
raise ArgumentError, "Type mismatch" if @type != inflector.decode_type(changeset.type)

@store.insert(changeset, to_query)
end
Expand All @@ -90,16 +90,18 @@ def delete(resource)
end

def inspect
type = @type.nil? ? "" : "[#{Inflector.classify(@type)}]"
type = @type.nil? ? "" : "[#{@type}]"
query = to_query
query = query.empty? ? "" : " #{query.inspect}"
"#<#{self.class}#{type}#{query}>"
end

private

attr_reader :inflector

def uri_builder
@uri_builder ||= URIBuilder.new(@inflector)
@uri_builder ||= URIBuilder.new(inflector)
end

def to_query
Expand All @@ -124,16 +126,16 @@ def other_params
end

def filter_query
@inflector.encode_keys(@filter)
inflector.encode_keys(@filter)
end

def include_query
@include.map { |path| @inflector.encode_key(path) }.compact.uniq.join(",")
@include.map { |path| inflector.encode_key(path) }.compact.uniq.join(",")
end

def fields_query
@inflector.encode_types(@fields) do |fields|
fields.map { |field| @inflector.encode_key(field) }.compact.uniq.join(",")
inflector.encode_types(@fields) do |fields|
fields.map { |field| inflector.encode_key(field) }.compact.uniq.join(",")
end
end

Expand All @@ -142,7 +144,7 @@ def sort_query
end

def sort_key(key, direction)
encoded_key = @inflector.encode_key(key)
encoded_key = inflector.encode_key(key)
case direction
when :asc
encoded_key
Expand Down
4 changes: 4 additions & 0 deletions lib/lurch/relationship.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ def loaded?
!!defined?(@data)
end

def inflector
@store.inflector
end

def respond_to_missing?(method, all)
raise Errors::RelationshipNotLoaded, @relationship_key unless loaded?

Expand Down
2 changes: 1 addition & 1 deletion lib/lurch/relationship/has_many.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def initialize(store, relationship_key, document)
end

def inspect
suffix = @data.first ? "[#{Inflector.classify(@data.first.type)}]" : ""
suffix = @data.first ? "[#{@data.first.type}]" : ""
"#<#{self.class}#{suffix} size: #{@data.size}>"
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/lurch/relationship/has_one.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ def initialize(store, relationship_key, document)
if document["data"].nil?
@data = nil
else
@type = Inflector.decode_type(document["data"]["type"])
@type = inflector.decode_type(document["data"]["type"])
@id = document["data"]["id"]
@data = Resource.new(@store, @type, @id)
end
end

def inspect
@data.nil? ? "#<#{self.class} nil>" : "#<#{self.class}[#{Inflector.classify(@type)}] id: #{@id.inspect}>"
@data.nil? ? "#<#{self.class} nil>" : "#<#{self.class}[#{@type}] id: #{@id.inspect}>"
end
end
end
Expand Down
16 changes: 6 additions & 10 deletions lib/lurch/resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class Resource

def initialize(store, type, id)
@store = store
@type = Inflector.decode_type(type)
@type = @store.inflector.decode_type(type)
@id = id
end

Expand All @@ -20,13 +20,13 @@ def fetch
end

def attributes
raise Errors::ResourceNotLoaded, resource_class_name unless loaded?
raise Errors::ResourceNotLoaded, type unless loaded?

resource_from_store.attributes
end

def relationships
raise Errors::ResourceNotLoaded, resource_class_name unless loaded?
raise Errors::ResourceNotLoaded, type unless loaded?

resource_from_store.relationships
end
Expand All @@ -40,22 +40,18 @@ def eql?(other)
end

def [](attribute)
raise Errors::ResourceNotLoaded, resource_class_name unless loaded?
raise Errors::ResourceNotLoaded, type unless loaded?

resource_from_store.attribute(attribute)
end

def resource_class_name
Inflector.classify(type)
end

def inspect
inspection = if loaded?
attributes.map { |name, value| "#{name}: #{value.inspect}" }.join(", ")
else
"not loaded"
end
"#<#{self.class}[#{resource_class_name}] id: #{id.inspect}, #{inspection}>"
"#<#{self.class}[#{type}] id: #{id.inspect}, #{inspection}>"
end

private
Expand All @@ -71,7 +67,7 @@ def respond_to_missing?(method, all)
end

def method_missing(method, *arguments, &block)
raise Errors::ResourceNotLoaded, resource_class_name unless loaded?
raise Errors::ResourceNotLoaded, type unless loaded?

return resource_from_store.attribute(method) if resource_from_store.attribute?(method)

Expand Down
19 changes: 13 additions & 6 deletions lib/lurch/store.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ def peek(type, id)
Resource.new(self, stored_resource.type, stored_resource.id)
end

def save(changeset, query = {})
def save(changeset, query = {}) # rubocop:disable Metrics/AbcSize
return insert(changeset) if changeset.id.nil?

url = uri_builder.resource_uri(changeset.type, changeset.id, query)
url = uri_builder.resource_uri(
inflector.decode_type(changeset.type),
changeset.id, query
)

document = @client.patch(url, payload_builder.build(changeset))
process_document(document)
Expand All @@ -35,7 +38,8 @@ def save(changeset, query = {})
def insert(changeset, query = {})
return save(changeset) unless changeset.id.nil?

url = uri_builder.resources_uri(changeset.type, query)
type = inflector.decode_type(changeset.type)
url = uri_builder.resources_uri(type, query)

document = @client.post(url, payload_builder.build(changeset))
process_document(document)
Expand Down Expand Up @@ -75,7 +79,7 @@ def load_from_url(url)

# @private
def resource_from_store(type, id)
normalized_type = Inflector.decode_type(type)
normalized_type = inflector.decode_type(type)
@store[normalized_type][id]
end

Expand All @@ -84,12 +88,15 @@ def query
Query.new(self, inflector)
end

private

# @private
def inflector
@inflector ||= Inflector.new(@config.inflection_mode, @config.types_mode)
end

private

def changeset_type(changeset); end

def uri_builder
@uri_builder ||= URIBuilder.new(inflector)
end
Expand Down
10 changes: 7 additions & 3 deletions lib/lurch/stored_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def id
end

def type
@type ||= Inflector.decode_type(@resource_object["type"])
@type ||= inflector.decode_type(@resource_object["type"])
end

def attributes
Expand Down Expand Up @@ -41,15 +41,19 @@ def relationship(name)

private

def inflector
@store.inflector
end

def fixed_attributes
@fixed_attributes ||= resource_attributes.each_with_object({}) do |(key, value), hash|
hash[Inflector.decode_key(key)] = value
hash[inflector.decode_key(key)] = value
end
end

def fixed_relationships
@fixed_relationships ||= resource_relationships.each_with_object({}) do |(key, value), hash|
relationship_key = Inflector.decode_key(key)
relationship_key = inflector.decode_key(key)
hash[relationship_key] = Relationship.from_document(@store, relationship_key, value)
end
end
Expand Down
2 changes: 1 addition & 1 deletion lurch.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ Gem::Specification.new do |gem|
gem.files = `git ls-files`.split($RS)
gem.require_paths = ["lib"]

gem.add_dependency("dry-inflector", "< 1.0")
gem.add_dependency("faraday", "< 1.0")
gem.add_dependency("inflecto", "~> 0.0")
gem.add_dependency("rack", ">= 1.0")
gem.add_dependency("typhoeus", "< 2.0")

Expand Down
2 changes: 1 addition & 1 deletion test/lurch/test_fetch_resources.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def test_fetch_resource_that_includes_resource_identifiers_only
refute phone_number.loaded?
assert phone_number.inspect
err = assert_raises(Lurch::Errors::ResourceNotLoaded) { phone_number.name }
assert_equal "Resource (PhoneNumber) not loaded, try calling #fetch first.", err.message
assert_equal "Resource (phone_numbers) not loaded, try calling #fetch first.", err.message

stub_get("#{phone_number_type}/1", @response_factory.phone_number_response("1", "Cell", "111-222-3344"))

Expand Down