Skip to content
This repository has been archived by the owner on May 15, 2024. It is now read-only.

uninitialized constant Zermelo::Records #22

Open
scalp42 opened this issue Nov 21, 2018 · 8 comments
Open

uninitialized constant Zermelo::Records #22

scalp42 opened this issue Nov 21, 2018 · 8 comments

Comments

@scalp42
Copy link

scalp42 commented Nov 21, 2018

Hi @ali-graham,

Running into an issue when trying to include Zermelo:

> bundle exec pry
[1] pry(main)> require 'zermelo'
=> true
[2] pry(main)> require 'redis'
=> true
[3] pry(main)> Zermelo.redis = Redis.new(host: '127.0.0.1', db: 0)
=> #<Redis client v4.0.3 for redis://127.0.0.1:6379/0>
[4] pry(main)> class Test; include Zermelo::Records::Redis; end
NameError: uninitialized constant Zermelo::Records
from (pry):4:in `<class:Test>'
[5] pry(main)> class Test; include ::Zermelo::Records::Redis; end
NameError: uninitialized constant Zermelo::Records
from (pry):5:in `<class:Test>'

Simple Gemfile:

source 'https://rubygems.org'

gem 'redis'
gem 'zermelo', github: 'flapjack/zermelo', branch: 'master'

group :dev do
  gem 'awesome_print'
  gem 'pry'
  gem 'rubocop'
end
Using zermelo 1.4.3 from git://github.com/flapjack/zermelo.git (at master@d7adfdd)

I must be missing something but I also tried to require zermelo/records/redis directly.

Thanks in advance for the help!

UPDATE: it looks like you need to require more than just the gem

=> true
[2] pry(main)> class Post
[2] pry(main)*   include Zermelo::Records::Redis
[2] pry(main)* end
NameError: uninitialized constant Zermelo::Records::Redis
Did you mean?  Zermelo::Records::RedisSet
from (pry):3:in `<class:Post>'
[3] pry(main)>
@scalp42
Copy link
Author

scalp42 commented Nov 21, 2018

Digging more, it doesn't appear that the Redis module exists: https://github.com/flapjack/zermelo/blob/master/lib/zermelo/records/redis.rb#L7-L27

Any chance you could share more insight regarding when to pick the RedisSet or RedisSortedSet?

Thanks in advance :bowtie:

@scalp42
Copy link
Author

scalp42 commented Nov 21, 2018

Using the Post class example and fixing the include:

class Post
  include Zermelo::Records::RedisSet
  define_attributes :title     => :string,
                    :score     => :integer,
                    :timestamp => :timestamp,
                    :published => :boolean
end

It appears that the id is not automatically generated:

[20] pry(main)> post = Post.new(:title => 'Introduction to Zermelo',
[20] pry(main)* :score => 100, :timestamp => Time.parse('Jan 1 2000'), :published => false)
=> #<Post:0x00007f831ca0f608
 @attributes=
  {"id"=>nil,
   "title"=>"Introduction to Zermelo",
   "score"=>100,
   "timestamp"=>2000-01-01 00:00:00 -0800,
   "published"=>false},
 @is_new=true>

Which leads to calling changed? method on nil:

[21] pry(main)> post.save
NoMethodError: undefined method `changed?' for nil:NilClass
from /usr/local/lib/ruby/gems/2.5.0/gems/activemodel-5.2.1/lib/active_model/attribute_mutation_tracker.rb:49:in `changed?'

I'm not sure at this point if I'm supposed to keep track of the ids? Seems counter-intuitive but let me know.

I tried to pass an id by hand as well:

[23] pry(main)> p = Product.new(vendor: 'apple', name: 'news', id: 42)
=> #<Product:0x00007f831c991a00
 @attributes={"id"=>42, "name"=>"news", "vendor"=>"apple"},
 @is_new=true>
[24] pry(main)> p.save
=> false
[25] pry(main)> p.save
=> false
[26] pry(main)> p.errors
=> #<ActiveModel::Errors:0x00007f831f42c468
 @base=
  #<Product:0x00007f831c991a00
   @attributes={"id"=>42, "name"=>"news", "vendor"=>"apple"},
   @errors=#<ActiveModel::Errors:0x00007f831f42c468 ...>,
   @is_new=true,
   @validation_context=nil>,
 @details={:id=>[{:error=>"should be String but is Integer"}]},
 @messages={:id=>["should be String but is Integer"]}>


[27] pry(main)> p = Product.new(vendor: 'apple', name: 'news', id: '42')
=> #<Product:0x00007f831d0e9640
 @attributes={"id"=>"42", "name"=>"news", "vendor"=>"apple"},
 @is_new=true>
[28] pry(main)> p.save
NoMethodError: undefined method `multi' for nil:NilClass
from /usr/local/lib/ruby/gems/2.5.0/bundler/gems/zermelo-d7adfdd0b29a/lib/zermelo/backends/redis.rb:120:in `begin_transaction'

@ali-graham
Copy link
Member

It's looking like you've not initialised Zermelo.redis to a valid Redis connection? ( https://github.com/flapjack/zermelo#initialisation )

For the inclusion of the gem, in this case

require 'zermelo'
require 'zermelo/records/redis'

should be enough in terms of the requires, and the first of those would be implicit in the Gemfile, yeah.

Ids are left up to the implementing classes, at the moment. It's a design decision based on what I needed it for (an app that wanted that level of control), but I did have plans to make that more pluggable and provide some standard implementations.

@ali-graham
Copy link
Member

Also, for a Set or SortedSet, it really depends on how you'd want to query that data. Is set inclusion all you care about, or is the order (and possible range querying) desirable?

@scalp42
Copy link
Author

scalp42 commented Nov 22, 2018

It's looking like you've not initialised Zermelo.redis to a valid Redis connection? ( flapjack/zermelo#initialisation )

Thanks for the quick answer!

Indeed after requiring the redis gem, I got a little further but unfortunately a different error popped up:

[31] pry(main)> require 'redis'
=> true
[32] pry(main)> Zermelo.redis = Redis.new(host: '127.0.0.1', db: 0)
=> #<Redis client v4.0.3 for redis://127.0.0.1:6379/0>
[33] pry(main)> p
=> #<Product:0x00007f831d0e9640
 @attributes={"id"=>"42", "name"=>"news", "vendor"=>"apple"},
 @errors=
  #<ActiveModel::Errors:0x00007f831d08a9d8
   @base=#<Product:0x00007f831d0e9640 ...>,
   @details={},
   @messages={}>,
 @is_new=true,
 @validation_context=nil>
[34] pry(main)> p.save
NoMethodError: undefined method `forgetting_assignment' for ["id", "42"]:Array
from /usr/local/lib/ruby/gems/2.5.0/gems/activemodel-5.2.1/lib/active_model/dirty.rb:270:in `each'

For what it's worth, when trying to run p.save, redis-cli monitor returns the following:

1542845567.443789 [0 127.0.0.1:62114] "multi"
1542845567.444801 [0 127.0.0.1:62114] "sadd" "product::attrs:ids" "42"
1542845567.444820 [0 127.0.0.1:62114] "hmset" "product:42:attrs" "name" "news" "vendor" "apple"
1542845567.444844 [0 127.0.0.1:62114] "exec"

I'm not too sure about the forgetting_assignment if I'm missing something in the model.

Thanks again for the help, much much appreciated!

@ali-graham
Copy link
Member

Sorry, I've not been well -- I haven't tested this with ActiveModel past v4, so something may have changed in that. I'll fix this when I get some time.

@scalp42
Copy link
Author

scalp42 commented Nov 26, 2018

@ali-graham no worries please, I just wanted to give some feedback and making sure I was not missing anything.

Thanks for sharing your wok with this gem, it's much appreciated and I hope you feel better soon 👨‍⚕️

@ali-graham
Copy link
Member

I had some travel too, so my time's been a bit broken up. There have been some extensive changes in recent versions of ActiveModel, I'll iron out the remaining bugs in the branch when I get a chance (it seems like my code can continue doing what it was doing, it just needs to use new wrapper objects etc.), and then work out the proper points to conditionally use those in master in order to support both older and recent versions of AM.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants