Skip to content

Introduce ActiveResource::WhereClause #422

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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: 1 addition & 0 deletions lib/active_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ module ActiveResource
autoload :InheritingHash
autoload :Validations
autoload :Collection
autoload :WhereClause

if ActiveSupport::VERSION::STRING >= "7.1"
def self.deprecator
Expand Down
4 changes: 2 additions & 2 deletions lib/active_resource/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1037,12 +1037,12 @@ def last(*args)
# This is an alias for find(:all). You can pass in all the same
# arguments to this method as you can to <tt>find(:all)</tt>
def all(*args)
find(:all, *args)
WhereClause.new(self, *args)
end

def where(clauses = {})
raise ArgumentError, "expected a clauses Hash, got #{clauses.inspect}" unless clauses.is_a? Hash
find(:all, params: clauses)
all(params: clauses)
end


Expand Down
47 changes: 47 additions & 0 deletions lib/active_resource/where_clause.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# frozen_string_literal: true

module ActiveResource
class WhereClause < BasicObject # :nodoc:
delegate_missing_to :resources

def initialize(resource_class, options = {})
@resource_class = resource_class
@options = options
@resources = nil
@loaded = false
end

def where(clauses = {})
all(params: clauses)
end

def all(options = {})
WhereClause.new(@resource_class, @options.deep_merge(options))
end

def load
unless @loaded
@resources = @resource_class.find(:all, @options)
@loaded = true
end

self
end

def reload
reset
load
end

private
def resources
load
@resources
end

def reset
@resources = nil
@loaded = false
end
end
end
60 changes: 60 additions & 0 deletions test/cases/finder_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,66 @@ def test_where_with_clauses
assert_kind_of StreetAddress, addresses.first
end

def test_where_with_multiple_where_clauses
ActiveResource::HttpMock.respond_to.get "/people.json?id=2&name=david", {}, @people_david

people = Person.where(id: 2).where(name: "david")
assert_equal 1, people.size
assert_kind_of Person, people.first
assert_equal 2, people.first.id
assert_equal "David", people.first.name
end

def test_where_chained_from_all
ActiveResource::HttpMock.respond_to.get "/records.json?id=2", {}, @people_david

people = Person.all(from: "/records.json").where(id: 2)
assert_equal 1, people.size
assert_kind_of Person, people.first
assert_equal 2, people.first.id
assert_equal "David", people.first.name
end

def test_where_with_chained_into_all
ActiveResource::HttpMock.respond_to.get "/records.json?id=2&name=david", {}, @people_david

people = Person.where(id: 2).all(from: "/records.json", params: { name: "david" })
assert_equal 1, people.size
assert_kind_of Person, people.first
assert_equal 2, people.first.id
assert_equal "David", people.first.name
end

def test_where_loading
ActiveResource::HttpMock.respond_to.get "/people.json?id=2", {}, @people_david
people = Person.where(id: 2)

assert_changes -> { ActiveResource::HttpMock.requests.count }, from: 0, to: 1 do
people.load
end
assert_no_changes -> { ActiveResource::HttpMock.requests.count }, from: 1 do
10.times { people.load }
end
end

def test_where_reloading
ActiveResource::HttpMock.respond_to.get "/people.json?id=2", {}, @people_david
people = Person.where(id: 2)

assert_changes -> { ActiveResource::HttpMock.requests.count }, from: 0, to: 1 do
assert_equal 1, people.size
end
assert_no_changes -> { ActiveResource::HttpMock.requests.count }, from: 1 do
assert_equal 1, people.size
end
assert_changes -> { ActiveResource::HttpMock.requests.count }, from: 1, to: 2 do
people.reload
end
assert_no_changes -> { ActiveResource::HttpMock.requests.count }, from: 2 do
assert_equal 1, people.size
end
end

def test_where_with_clause_in
ActiveResource::HttpMock.respond_to { |m| m.get "/people.json?id%5B%5D=2", {}, @people_david }
people = Person.where(id: [2])
Expand Down
Loading