Mongoid: Caching Eager Loaded Documents - ruby-on-rails

We have this code:
class Band
include Mongoid::Document
has_many :albums
end
class Album
include Mongoid::Document
belongs_to :band
end
#bands = Band.includes(:albums).entries
This is great because now I can run #bands.first.albums without hitting the DB.
But now, if we write this includes to the rails cache...
Rails.cache.write('bands', #bands)
...we then read the cache.
bands = Rails.cache.read('bands')
This returns an array of band documents...
[#<Band _id: 536a53c969702d208f240000, created_at: 2014-05-07 15:39:53 UTC, updated_at: 2014-05-08 15:55:29 UTC, name: "Pink Floyd", fan_count: 394857, #<Band _id: 536adf2a69702d1574130000, created_at: 2014-05-08 01:34:34 UTC, updated_at: 2014-05-08 01:35:40 UTC, name: "Tool", fan_count: 2958394, #<Band _id: 536bcad169702d743e1e0000, created_at: 2014-05-08 18:20:01 UTC, updated_at: 2014-05-08 18:27:10 UTC, name: "My Morning Jacket", fan_count: 3945734]
...and then we can't get the albums.
bands.first.albums
NoMethodError: undefined method 'albums' for #<Array:0x00000104df50c0>
Is there a special way to cache these eager loaded documents with Rails or Mongoid?
FYI we're using Mongoid 4.

That looks like to be a eager load issue on Mongoid.. Can you go to https://github.com/mongoid/mongoid/issues/new and open a new issue, so we can work on a fix for it, before releasing the final 4.0.0 version.
thanks

Related

Rails console output to recreate objects

I accidentally deleted 1000 objects from a database and now trying to recreate these objects. Thankfully I was able to scroll through my console output and find the records. I copy and pasted the console output which is in this (greatly shortened) format:
[#<Assignment id: 276503, school_id: 2091, listing_id: 251572, created_at: "2018-08-30 05:02:36", updated_at: "2018-08-30 05:02:36">, #<Assignment id: 279532, school_id: 1233, listing_id: 252702, created_at: "2018-08-30 06:19:12", updated_at: "2018-08-30 06:19:12">]
#...
I can't get the console to assign this output to a variable so I can figure out how to use this data to recreate the objects in the db:
irb(main):040:0> a = [#<Assignment id: 276503, school_id: 2091, listing_id: 251572, created_at: "2018-08-30 05:02:36", updated_at: "2018-08-30 05:02:36">, #<Assignment id: 279532, school_id: 1233, listing_id: 252702, created_at: "2018-08-30 06:19:12", updated_at: "2018-08-30 06:19:12">]
irb(main):041:1*
Does anyone have ideas how to turn this console output back into objects in my db?
If you have the problems with assigning a huge array to a variable in the console, you can try to use rake task.
array.each do |e|
options = e.split(',')
school_id = options.detect{|i| i.match?(/school_id/)}.split(':').last
listing_id = options.detect{|i| i.match?(/listing_id/)}.split(':').last
Assignment.create(school_id: school_id, listing_id: listing.id)
end
This should work. It is quite consuming, but from another perspective easy and fast.
I would paste that output on sublime or any other text editor and then format
to become something useful...
A bunch of inserts using SQL or just .create() that i would then paste it on the console

Rails 5.2 belongs_to association not linking to parent

I have these models
class Version
has_many :bids
end
class Bid
belongs_to :version
end
in the console:
> bid = Bid.first
which returns
> #<Bid id: 8 version_id: 5, deleted_at: nil, created_at: "2018-09-06 00:32:32", updated_at: "2018-09-06 00:32:32", created_by_id: 3, updated_by_id: 3, selected: true>
but if i try to call the version it returns nil. the version is there though
> bid.version
> nil
> Version.find(bid.version_id)
> #<Version id: 5, effective_date: "2018-09-05 23:36:24", end_date: nil, created_at: "2018-09-05 23:36:24", updated_at: "2018-09-05 23:36:24", created_by_id: nil>
what is going on? what could I be doing wrong?
So it turns out that object.version is an existing rails method. if i change the relationship to belongs_to :pricing_version the code works.
Anyone with this issue in the future just avoid naming their class Version

Multiple file upload carrierwave mongoid

I have been having issues with implementing multiple file upload with the carrierwave-mongoid gem. Multiple file upload with carrierwave is well documented for ActiveRecord but not Mongoid. I have tried to mirror the ActiveRecord tutorials are much as possible but cannot seem to get it right. My uploader is mounted as follows.
class Product
include Mongoid::Document
.....
attr_accessor :product_images, :product_images_cache
mount_uploaders :product_images, ProductImageUploader
end
The main issue that I am having is with saving the uploader instance. In my controller with a pry in the create block, I am able to create a Product instance that contains the uploader instances, but when I try to retrieve the Uploader instance via the rails console the array is empty. see below.
[22] pry(#<ProductsController>)> #product
=> #<Product _id: 58726dae75e505a9ddc43f20, name: "Post", description: "This is a post\r\n", rating: nil, category_id: 1, seller_id: 1, approved: false, approved_by: nil>
[23] pry(#<ProductsController>)> #product.product_images_urls
=> ["/uploads/tmp/1483894190-43485-0005-7191/download.jpeg", "/uploads/tmp/1483894190-43485-0006-6662/TRACK.jpg"]
[24] pry(#<ProductsController>)> Product.last
=> #<Product _id: 58726dae75e505a9ddc43f20, name: "Post", description: "This is a post\r\n", rating: nil, category_id: 1, seller_id: 1, approved: false, approved_by: nil>
[25] pry(#<ProductsController>)> Product.last.product_images_urls
=> []
What is notice here is that the images are not being save in the uploads directory. I have spent quite a bit of time researching this but no leads. Any help will be greatly appreciated.
Update: This method is currently not supported by CarrierWave-Mongoid. My initial thoughts where right the Uploader object was not being created/saved https://github.com/carrierwaveuploader/carrierwave-mongoid/issues/155. I am currently looking for a workaround for this - any pointer in this direction will be great

time type field getting bad default datetime if it is invalid

Terrible title, but this is what I have:
Loading development environment (Rails 3.2.8)
1.9.3p194 :001 > Product
=> Product(id: integer, name: string, date: datetime, created_at: datetime, updated_at: datetime, end_time: datetime, start_time: time)
1.9.3p194 :002 > p = Product.new
=> #<Product id: nil, name: nil, date: nil, created_at: nil, updated_at: nil, end_time: nil, start_time: nil>
1.9.3p194 :003 > p.start_time = "foo"
=> "foo"
1.9.3p194 :004 > p.start_time
=> 2000-01-01 00:00:00 UTC
I wouldn't expect an invalid time to parse into a valid one. This is causing me issues with validations from form submissions.
This is somewhat related: Rails 3 - Validation for Time existence
And leads to this issue in github: https://github.com/rails/rails/issues/6045
I tried eye tracing the code, but nothing pops out at me except that the "foo" shouldn't parse and it should return nil.
EDIT: I created a sample app that displays this exact behavior https://github.com/danbeaulieu/test-app
But really it's just a bare bones app with a single model.
You can use validates_timeliness which validates dates, times and datetimes .
Then in your model you can do
validates_time :start_time
OR have a look at my GIST to handle default date validation

Mongoid persistance problems with a 1 to many association

I have the following model:
class Bill
. . . some fields . . .
belongs_to :sponsor, :class_name => "Legislator"
end
class Legislator
.. .some fields . . .
has_many :bills
end
I get this strange behavior, but I am sure this is something simple:
Loading development environment (Rails 3.0.7)
b = Bill.first
l = Legislator.first
l.bills << b
l.save
=> true
(I can view l.bills, but l.bills.all.to_a.count is 0)
l.govtrack_id
=> 400001
ruby-1.9.2-p180 :007 > Legislator.where(govtrack_id: 400001).first.bills
=> []
So I can create the association and view it. The save is successful, but when I retrieve the object, the association is gone . . . no errors. I'm confused, what am I missing?
You're missing inverse_of on your Legislator model. I ran a quick test (to make sure there wasn't a Mongoid issue). My models were thus:
class Bill
include Mongoid::Document
include Mongoid::Timestamps
field :name
belongs_to :sponsor, :class_name => "Legislator"
end
class Legislator
include Mongoid::Document
include Mongoid::Timestamps
field :govtrack_id
has_many :bills, :inverse_of => :sponsor
end
And console output from the test:
ruby-1.9.2-p180 > Bill.create(:name => "A new bill")
=> #<Bill _id: 4e0822636a4f1d11c1000001, _type: nil, created_at: 2011-06-27 06:25:39 UTC, updated_at: 2011-06-27 06:25:39 UTC, name: "A new bill", sponsor_id: nil>
ruby-1.9.2-p180 > Legislator.create(:govtrack_id => "400123")
=> #<Legislator _id: 4e0822786a4f1d11c1000002, _type: nil, created_at: 2011-06-27 06:26:00 UTC, updated_at: 2011-06-27 06:26:00 UTC, govtrack_id: "400123">
ruby-1.9.2-p180 > l = Legislator.first
ruby-1.9.2-p180 > l.bills << Bill.first
=> [#<Bill _id: 4e0822636a4f1d11c1000001, _type: nil, created_at: 2011-06-27 06:25:39 UTC, updated_at: 2011-06-27 06:26:08 UTC, name: "A new bill", sponsor_id: BSON::ObjectId('4e0822786a4f1d11c1000002')>]
ruby-1.9.2-p180 > l.save!
=> true
ruby-1.9.2-p180 > Bill.first.sponsor.govtrack_id
=> "400123"
ruby-1.9.2-p180 > Legislator.first.bills
=> [#<Bill _id: 4e0822636a4f1d11c1000001, _type: nil, created_at: 2011-06-27 06:25:39 UTC, updated_at: 2011-06-27 06:26:08 UTC, name: "A new bill", sponsor_id: BSON::ObjectId('4e0822786a4f1d11c1000002')>]

Resources