Create or increment a field in Mongoid with Rails 4 - ruby-on-rails

I have a model like this:
class Invoice
include Mongoid::Document
field :local, type: String
field :date, type: DateTime
field :total, type: Float
end
class LogInvoice
include Mongoid::Document
field :date, type: Date
field :local, type: String
field :summary, type: Hash
end
The field summary is a Hash like this:
summary = {invoices : 0, amount : 0.0}
For each invoice stored, I must create an LogInvoice for that day with total number of Invoice (count of Invoice) in LogInvoice.summary[:invoices] and with the total ammount of money (summatory of Invoice.total) in LogInvoice.summary[:amount]
If the Invoice exist I must to update the LogInvoice of that day.
I can't know if a object existe because LogInvoice.find() returns an exception if it doesn't, so how can I update an existing object LogInvoice or created if it doesn't?
Thank you

If I've understood your question you should do something like this:
my_invoice_criteria = Invoice.all # or Invoice.where date: the_date_I_want or anything else
my_invoice_criteria.each do |invoice|
log_invoice = LogInvoice.find_or_create_by date: invoice.obtain_proper_date
#Use this for atomic persistence
log_invoice.inc :"summary.invoices" => 1
log_invoice.inc :"summary.amount" => invoice.total
#Use this for standard persistence
log_invoice.summary[:invoices]+=1
log_invoice.summary[:amount]+=invoice.total
log_invoice.save
end
Ref:
Atomic persistence Docs
Standard persistence Docs

Related

Chewy gem deserializes Elasticsearch date types to string

When retrieving results from ES using Chewy, the date-typed results are returned as Ruby strings.
My index is defined just like:
class OrdersIndex < Chewy::Index
define_type Order do
field :id, type: "keyword"
field :created_at, type: "date"
end
end
When the results are retrieved:
OrdersIndex.order(created_at: :desc).first.created_at.class
# => String
Is there a way to deserialize this date field in a Ruby date object automatically, without having to explicitly map the results using Time#parse?

How to update one attribute in mongoid

How to update only :share_count, maybe this should be done with upsert ?
I use ruby on rails and mongoid
class FeedEntry
include Mongoid::Document
require 'social_shares'
field :name, type: String
field :url, type: String
field :share_count, type: Integer
before_save :load_shares
def load_shares
self.share_count = SocialShares.total url, %w(sharedcount)
end
def self.update_shares_today
#feed_entries = FeedEntry.today.all
#feed_entries.each do |feed_entry|
feed_entry.update
end
end
end
count = SocialShares.total url, %w(sharedcount)
update_attributes share_count: count

Mongoid Rails - Is there a way to check the field's datatype before saving?

I have this class ProfitLoss which consists of these fields. I want to call this method zero_if_blank on before_validation as before_save is not working and what i want to do is assign 0 to those values which are blank and are of Integer when coming from the form. I searched a lot like the Mysql columns_hash but didn't find any method to give the type of each field in mongo.
class ProfitLoss < Generic
include Mongoid::Document
include Mongoid::Timestamps
include MongoMysqlRelations
field :fiscal_year, type: String
field :sales_excluding_other_incomes, type: Integer
field :other_incomes, type: Integer
field :closing_stock, type: Integer
before_validation :zero_if_blank
def zero_if_blank
pp self.columns_hash.each {|k,v| puts "#{k} => #{v.type}"}
end
end
this piece of code did the work :)
def zero_if_blank
self.fields.each do |k,v|
if v.type == Integer && self.attributes[k] == nil
self.__send__("#{k}=", 0)
end
end
end

Mongoid fields auto sum

Everyone! I have a model:
class Model
include Mongoid::Document
field :price1, :type =>Integer
field :price2, :type =>Integer
field :price3, :type =>Integer <== I want this field to be always result of price1 + price2
end
My question is: How can I make :price3 to be always autofilled by sum of price1 + price2.
Thank you very much for help!
You want to use the callbacks interface. There are various callbacks exposed such as:
require "mongoid"
require "pp"
Mongoid.configure.connect_to("test")
class Model
include Mongoid::Document
field :price1, type: Integer
field :price2, type: Integer
field :price3, type: Integer
store_in collection: "mymodel"
before_save do |document|
document.price3 = document.price1 + document.price2
end
end
model = Model.new
model.price1 = 2
model.price2 = 3
model.save
Which results in the "price3" field being set to the sum of the other two values.

Parsing an RSS Feed in Ruby

So I'm new to Ruby on Rails, but I'm basically trying to parse through a feed using SimpleRSS, and then store various values and display it. I'm using MongoDB/the mongoid gem as the database.
I can parse through the feed, but then none of the values get correctly stored.
class FeedEntry
include Mongoid::Document
require 'rubygems'
require 'simple-rss'
require 'open-uri'
field :name, type: String
field :summary, type: String
field :url, type: String
field :published_at, type: DateTime
field :guid, type: Integer
def self.rssFeeder(feed_url)
feed = SimpleRSS.parse open(feed_url)
feed.items.each do |entry|
unless FeedEntry.where(guid: entry.id).exists?
FeedEntry.create!(
name: entry.title,
summary: entry.summary,
url: entry.link,
published_at: entry.pubDate,
guid: entry.id
)
end
end
end
end
I can get that FeedEntry.count is 76, but all of the values stored are nil.
Does anyone see a clear error?

Resources