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

Ruby3, faraday2 compatibility, remove parse native collection override templates #74

Open
wants to merge 16 commits into
base: feature/1.10.0
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 10 additions & 9 deletions Gemfile.lock
Expand Up @@ -2,14 +2,14 @@ PATH
remote: .
specs:
parse-stack (1.10.0)
active_model_serializers (>= 0.9, < 1)
activemodel (>= 5, < 7)
activesupport (>= 5, < 7)
faraday (< 1)
faraday_middleware (>= 0.9, < 2)
moneta (< 2)
parallel (>= 1.6, < 2)
rack (>= 2.0.6, < 3)
active_model_serializers (>= 0.9)
activemodel (>= 5)
activesupport (>= 5)
faraday
faraday_middleware (>= 0.9)
moneta
parallel (>= 1.6)
rack (>= 2.0.6)

GEM
remote: https://rubygems.org/
Expand Down Expand Up @@ -154,7 +154,8 @@ GEM
zeitwerk (2.4.2)

PLATFORMS
ruby
x86_64-darwin-20
x86_64-linux

DEPENDENCIES
byebug
Expand Down
33 changes: 33 additions & 0 deletions README.md
Expand Up @@ -647,6 +647,39 @@ data.acl # => ACL({"role:Admin"=>{"read"=>true, "write"=>true}})

For more information about Parse record ACLs, see the documentation at [Security](http://docs.parseplatform.org/rest/guide/#security)

## Builtin parse collections

These classes match parse builtin collections. Do not redeclare them as rails autoloader don't support multiple class declarations. To add properties and methods to these classes, properly reopen them with overrides, using this class_eval method.

First, append this to config/application.rb

```ruby
##
# Don't autoload overrides but preload them instead
overrides = "#{Rails.root}/app/overrides"
Rails.autoloaders.main.ignore(overrides)

config.to_prepare do
Dir.glob("#{overrides}/**/*_override.rb").each do |override|
load override
end
end
```

Then, create the folder app/overrides/models. Create a file named [collection]_override.rb in this folder to reopen one of these classes. Example with the _User collection:

```ruby
# app/overrides/models/user_override.rb
Parse::User.class_eval do
has_many :created_articles, as: :articles, field: :creator

property :first_name
property :last_name
property :picture
end
```


### [Parse::Session](https://www.modernistik.com/gems/parse-stack/Parse/Session.html)
This class represents the data and columns contained in the standard Parse `_Session` collection. You may add additional properties and methods to this class. See [Session API Reference](https://www.modernistik.com/gems/parse-stack/Parse/Session.html). You may call `Parse.use_shortnames!` to use `Session` in addition to `Parse::Session`.

Expand Down
4 changes: 2 additions & 2 deletions lib/parse/client.rb
Expand Up @@ -2,7 +2,7 @@
require "faraday_middleware"
require "active_support"
require "moneta"
require "active_model_serializers"

require "active_support/inflector"
require "active_support/core_ext/object"
require "active_support/core_ext/string"
Expand Down Expand Up @@ -481,7 +481,7 @@ def request(method, uri = nil, body: nil, query: nil, headers: nil, opts: {})
retry
end
raise
rescue Faraday::Error::ClientError, Net::OpenTimeout => e
rescue Faraday::ClientError, Net::OpenTimeout => e
if _retry_count > 0
warn "[Parse:Retry] Retries remaining #{_retry_count} : #{_request}"
_retry_count -= 1
Expand Down
2 changes: 1 addition & 1 deletion lib/parse/client/body_builder.rb
Expand Up @@ -7,7 +7,7 @@
require_relative "protocol"
require "active_support"
require "active_support/core_ext"
require "active_model_serializers"


module Parse

Expand Down
2 changes: 1 addition & 1 deletion lib/parse/model/classes/user.rb
Expand Up @@ -29,7 +29,7 @@ class InvalidEmailAddress < Error; end

# The main class representing the _User table in Parse. A user can either be signed up or anonymous.
# All users need to have a username and a password, with email being optional but globally unique if set.
# You may add additional properties by redeclaring the class to match your specific schema.
# You may add additional properties by reopening the class to match your specific schema.
#
# The default schema for the {User} class is as follows:
#
Expand Down
4 changes: 4 additions & 0 deletions lib/parse/model/core/builder.rb
Expand Up @@ -43,6 +43,10 @@ def self.build!(schema)
raise ArgumentError, "No valid className provided for schema hash"
end

# Remove leading underscore, as ruby constants have to start with an uppercase letter

className = className[1..] if className[0] == '_'

begin
klass = Parse::Model.find_class className
klass = ::Object.const_get(className.to_parse_class) if klass.nil?
Expand Down
4 changes: 2 additions & 2 deletions lib/parse/model/core/properties.rb
Expand Up @@ -7,9 +7,9 @@
require "active_support/core_ext"
require "active_support/core_ext/object"
require "active_support/inflector"
require "active_model_serializers"

require "active_support/inflector"
require "active_model_serializers"

require "active_support/hash_with_indifferent_access"
require "time"

Expand Down
2 changes: 1 addition & 1 deletion lib/parse/model/date.rb
Expand Up @@ -10,7 +10,7 @@
require "active_support/core_ext/date/calculations"
require "active_support/core_ext/date_time/calculations"
require "active_support/core_ext/time/calculations"
require "active_model_serializers"

require_relative "model"

module Parse
Expand Down
2 changes: 1 addition & 1 deletion lib/parse/model/model.rb
Expand Up @@ -5,7 +5,7 @@
require "active_support"
require "active_support/inflector"
require "active_support/core_ext/object"
require "active_model_serializers"

require_relative "../client"

module Parse
Expand Down
9 changes: 5 additions & 4 deletions lib/parse/model/object.rb
Expand Up @@ -7,7 +7,7 @@
require "active_support/core_ext"
require "active_support/core_ext/object"
require "active_support/core_ext/string"
require "active_model_serializers"

require "time"
require "open-uri"

Expand Down Expand Up @@ -298,11 +298,12 @@ def as_json(opts = nil)
def initialize(opts = {})
if opts.is_a?(String) #then it's the objectId
@id = opts.to_s
elsif opts.is_a?(Hash)
elsif opts.respond_to?(:to_h)
#if the objectId is provided we will consider the object pristine
#and not track dirty items
dirty_track = opts[Parse::Model::OBJECT_ID] || opts[:objectId] || opts[:id]
apply_attributes!(opts, dirty_track: !dirty_track)
_attributes = opts.to_h
dirty_track = _attributes[Parse::Model::OBJECT_ID] || _attributes[:objectId] || _attributes[:id]
apply_attributes!(_attributes, dirty_track: !dirty_track)
end

# if no ACLs, then apply the class default acls
Expand Down
2 changes: 1 addition & 1 deletion lib/parse/model/pointer.rb
Expand Up @@ -5,7 +5,7 @@
require "active_support"
require "active_support/inflector"
require "active_support/core_ext"
require "active_model_serializers"

require_relative "model"

module Parse
Expand Down
2 changes: 1 addition & 1 deletion lib/parse/model/push.rb
Expand Up @@ -3,7 +3,7 @@

require_relative "../query.rb"
require_relative "../client.rb"
require "active_model_serializers"


module Parse
# This class represents the API to send push notification to devices that are
Expand Down
2 changes: 1 addition & 1 deletion lib/parse/query.rb
Expand Up @@ -6,7 +6,7 @@
require_relative "query/constraints"
require_relative "query/ordering"
require "active_model"
require "active_model_serializers"

require "active_support"
require "active_support/inflector"
require "active_support/core_ext"
Expand Down
10 changes: 5 additions & 5 deletions lib/parse/stack/generators/rails.rb
Expand Up @@ -16,11 +16,11 @@ class InstallGenerator < Rails::Generators::Base
# @!visibility private
def generate_initializer
copy_file "parse.rb", "config/initializers/parse.rb"
copy_file "model_user.rb", File.join("app/models", "user.rb")
copy_file "model_role.rb", File.join("app/models", "role.rb")
copy_file "model_session.rb", File.join("app/models", "session.rb")
copy_file "model_installation.rb", File.join("app/models", "installation.rb")
copy_file "webhooks.rb", File.join("app/models", "webhooks.rb")
#copy_file "model_user.rb", File.join("app/models", "user.rb")
#copy_file "model_role.rb", File.join("app/models", "role.rb")
#copy_file "model_session.rb", File.join("app/models", "session.rb")
#copy_file "model_installation.rb", File.join("app/models", "installation.rb")
#copy_file "webhooks.rb", File.join("app/models", "webhooks.rb")
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/parse/stack/tasks.rb
Expand Up @@ -117,7 +117,7 @@ def install_tasks

task :triggers => :verify_env do
endpoint = ENV["HOOKS_URL"]
Parse::Webhooks.register_triggers!(endpoint, { include_wildcard: true }) do |trigger, name|
Parse::Webhooks.register_triggers!(endpoint, include_wildcard: true) do |trigger, name|
puts "[+] #{trigger.to_s.ljust(12, " ")} - #{name}"
end
end
Expand Down
16 changes: 8 additions & 8 deletions lib/parse/webhooks.rb
Expand Up @@ -6,7 +6,7 @@
require "active_support/inflector"
require "active_support/core_ext/object"
require "active_support/core_ext"
require "active_model_serializers"

require "rack"
require_relative "client"
require_relative "stack"
Expand Down Expand Up @@ -53,18 +53,18 @@ def self.webhook_function(functionName, block = nil)
# @yield the body of the function to be evaluated in the scope of a {Parse::Webhooks::Payload} instance.
# @param block [Symbol] the name of the method to call, if no block is passed.
# @return (see Parse::Webhooks.route)
def self.webhook(type, block = nil)
def self.webhook(type, function=nil, &block)
if type == :function
unless block.is_a?(String) || block.is_a?(Symbol)
raise ArgumentError, "Invalid Cloud Code function name: #{block}"
unless function.is_a?(String) || function.is_a?(Symbol)
raise ArgumentError, "Invalid Cloud Code function name: #{function}"
end
Parse::Webhooks.route(:function, block, &Proc.new)
Parse::Webhooks.route(:function, function, block)
# then block must be a symbol or a string
else
if block_given?
Parse::Webhooks.route(type, self, &Proc.new)
else
if block
Parse::Webhooks.route(type, self, block)
else
Parse::Webhooks.route(type, self, function)
end
end
#if block
Expand Down
4 changes: 2 additions & 2 deletions lib/parse/webhooks/payload.rb
Expand Up @@ -7,7 +7,7 @@
require "active_support/core_ext/object"
require "active_support/core_ext/string"
require "active_support/core_ext"
require "active_model_serializers"


module Parse
class Webhooks
Expand Down Expand Up @@ -125,7 +125,7 @@ def parse_class
def parse_id
return nil unless @object.present?
@object[Parse::Model::OBJECT_ID] || @object[:objectId]
end;
end;
alias_method :objectId, :parse_id

# true if this is a webhook trigger request.
Expand Down
16 changes: 8 additions & 8 deletions parse-stack.gemspec
Expand Up @@ -27,14 +27,14 @@ Gem::Specification.new do |spec|
spec.require_paths = ["lib"]
spec.required_ruby_version = ">= 2.5.0"

spec.add_runtime_dependency "activemodel", [">= 5", "< 7"]
spec.add_runtime_dependency "active_model_serializers", [">= 0.9", "< 1"]
spec.add_runtime_dependency "activesupport", [">= 5", "< 7"]
spec.add_runtime_dependency "parallel", [">= 1.6", "< 2"]
spec.add_runtime_dependency "faraday", "< 1"
spec.add_runtime_dependency "faraday_middleware", [">= 0.9", "< 2"]
spec.add_runtime_dependency "moneta", "< 2"
spec.add_runtime_dependency "rack", ">= 2.0.6", "< 3"
spec.add_runtime_dependency "activemodel", [">= 5"]
spec.add_runtime_dependency "active_model_serializers", [">= 0.9"]
spec.add_runtime_dependency "activesupport", [">= 5"]
spec.add_runtime_dependency "parallel", [">= 1.6"]
spec.add_runtime_dependency "faraday"
spec.add_runtime_dependency "faraday_middleware", [">= 0.9"]
spec.add_runtime_dependency "moneta"
spec.add_runtime_dependency "rack", ">= 2.0.6"

# spec.post_install_message = <<UPGRADE
#
Expand Down
34 changes: 34 additions & 0 deletions test/lib/parse/models/attributes_test.rb
@@ -0,0 +1,34 @@
require_relative "../../../test_helper"

class TestAttributesClass < Parse::Object
property :main_name
end

# Mock Rails Action Controller Parameters
class ActionControllerParametersMock
def initialize(_attributes)
@attributes = _attributes
end

def to_h
@attributes
end
end

class TestAttributesModule < Minitest::Test
def setup
end

def test_attribution_from_hash
test_object = TestAttributesClass.new({main_name: 'test_name'})
assert_equal test_object.main_name, 'test_name'
assert_equal test_object.mainName, 'test_name'
end

def test_attribution_from_params
params = ActionControllerParametersMock.new({main_name: 'test_name'})
test_object = TestAttributesClass.new(params)
assert_equal test_object.main_name, 'test_name'
assert_equal test_object.mainName, 'test_name'
end
end