How to update one attribute in mongoid - ruby-on-rails

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

Related

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.

How to handle date fields in a non-model Rails form?

I am creating a non-model object that will be used with a Rails form builder by using ActiveModel. This is a Rails 3 project. Here's an example of what I have so far:
class SalesReport
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :promotion_code, :start_date, :end_date
def initialize(attributes = {})
attributes.each do |name, value|
send("#{name}=", value)
end
end
def persisted?
false
end
end
I happen to be using HAML and simple_form, but that's not important. Ultimately, I'm just using standard Rails date select fields:
= simple_form_for [:admin, #report], as: :report, url: admin_reports_path do |f|
= f.input :promotion_code, label: 'Promo Code'
= f.input :start_date, as: :date
= f.input :end_date, as: :date
= f.button :submit
Rails splits up the date fields into individual fields, so when the form is submitted, there are actually 3 date fields that are submitted:
{
"report" => {
"start_date(1i)" => "2014",
"start_date(2i)" => "4",
"start_date(3i)" => "1"
}
}
In my SalesReport object, I'm assigning the params to my attr methods, but I'm getting an error that I don't have a start_date(1i)= method, which I obviously haven't defined. Ultimately, I'd like to end up with a Date object that I can use instead of 3 separate fields.
How should I handle these date fields in my non-model object?
In your initialization you could manually assign the values from attributes to the class methods and down below override you start_date and end_date setter methods.
class SalesReport
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :promotion_code, :start_date, :end_date
def initialize(attributes = {})
#promotion_code = attributes['promotion_code']
year = attributes['start_date(1i)']
month = attributes['start_date(2i)']
day = attributes['start_date(3i)']
self.start_date = [year, month, day]
end
def start_date=(value)
if value.is_a?(Array)
#start_date = Date.new(value[0].to_i, value[1].to_i, value[2].to_i)
else
#start_date = value
end
end
def persisted?
false
end
end
This should allow you to give the setter a Date instance or an Array with the separate date elements and the setter will assign the correct date to #start_date.
Just do the same for #end_date.
Hope this can help you.

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?

Create or increment a field in Mongoid with Rails 4

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

Resources