rails error on not existing line - ruby-on-rails

I have an file named weekly_report_message.rb with 26 lines of code
module MessageTypes
class WeeklyReportMessage
include Mongoid::Document
include Mongoid::Timestamps
field :last_week_date, type: DateTime
field :this_week_date, type: DateTime
field :runs, type: Integer
field :runs_completed, type: Integer
field :distance, type: Float
field :distance_completed, type: Float
has_one :message
def basic_info
{
:last_week_date => !last_week_date.blank? ? last_week_date.strftime("%Y-%m-%d") : "",
:this_week_date => !this_week_date.blank? ? this_week_date.strftime("%Y-%m-%d") : "",
:runs => runs,
:runs_completed => runs_completed,
:distance => distance.round(1),
:distance_completed => distance_completed.round(1)
}
end
end
end
this code works ok on local machine and on production server in some cases but there one case in which basic_info method is called and this call results in error (only on production) which says:
undefined method `strftime' for nil:NilClass
app/models/message_types/weekly_report_message.rb:30:in `basic_info'
but I dont' have 30 lines in this file, the code was deployed, I checked with cat the code on server and is the same as on local, no matter what changes I make in this file it still give me this error, I restarted nginx but still have this error

Related

Querying a hash/bson document field in a collection

Hi there I have a Mongoid model, Spec, with mongoid-history gem added to it like this:
class Spec
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::History::Trackable
field :due_at, type: DateTime
track_history on: [:due_at],
:modifier_field => :modifier, # adds "referenced_in :modifier" to track who made the change, default is :modifier
:version_field => :version, # adds "field :version, :type => Integer" to track current version, default is :version
:track_create => false, # track document creation, default is false
:track_update => true, # track document updates, default is true
:track_destroy => false # track document destruction, default is false
end
spec = Spec.first
hist = spec.history_tracks.first
#=> { id: 123, modified: {due_at: 2017-06-12}, ... }
hist.modified.class
#=> BSON::Document
My question is, how can we query the modified field by the existence of its due_at field? A failed attempt looked like this:
spec.history_tracks.where(:'modified.due_at.exists' => true)
thanks in advance!!
This should work:
spec.history_tracks.not.where('modified.due_at' => nil)

Rails with MongoID Embedded Doc No Mapping To My Model

This is probably an issue on my part I have been struggling through some Rails and mongo samples to get up to speed (This is all for learning not for work.) This current project I get a JSON string from a api and I put that in mongo. So changing the document structure is not really an option. I then have been trying to map that into a Rails model so I can use the data.
The JSON is a report that contains many transactions that contain many LogLines.
Snippet from a doc
< Report _id: 583 c3baac0baf90a7ee26f6e,
ReportName: "PtSomIntPerfThreeLevelTest-1480341940187",
TestName: "PtSomIntPerfThreeLevelTest",
Transactions: [{
"colId" => "50437d6c-49c1",
"InfoPlate" => "[0SXdokPL-R13VQZwi]",
"rowId" => "1",
"sortDate" => 1480341975952,
"transactionType" => "REQUEST",
"description" => "description text for my document",
"startDate" => "11/28/2016 14:06:15",
"startDateMS" => 1480341975952,
"endDate" => "11/28/2016 14:06:23",
"endDateMS" => 1480341983069,
"finalEndDate" => "11/28/2016 14:06:23",
"finalEndDateMS" => 1480341983069,
"completeDuration" => "7 seconds",
"completeDurationMS" => 7117,
"feedProcessingDuration" => "7 seconds",
"feedProcessingDurationMS" => 7117,
"logLines" => [{
"id" => "1062b1ca-0f04",
"timestamp" => 1480341975952,
"transactionType" => "REQUEST",
"transactionStep" => "RECEIVE",
"collationId" => "50437d6c-49c1-438a-9b8",
"runName" => "runName-1480341940187",
"msg" => "Import default",
"elapsedSeconds" => "0.0",
"elapsedMS" => 0,
"InfoPlate" => "[0SXdokPL-3rmxW3oH]"
},
I have a report model, and a transaction model ( I will do LogLines after doing 1 at a time) My report model does fine I can get a single report doc based on an ID and it returns the report. I can then do a "report.transactions" and get a json blob of the transactions (almost always multiple transactions in a report) BUT its not recognized as a transaction model (will post all code below) So I cannot say transaction.InfoPlate I get a no such method error. I have relationships in my model but I also have a " field :Transactions, type: Array" which in looking at the rails cast on mongoid is not in theres. Without that I get nothing so the relationship "embeds_many :transactions" does not allow me to get a report.transaction. Sorry if that is confusing my Rails lingo is low. Short and sweat I want to get a report then get the transactions and be able to do transactions.ColID and get the col ID .
My goal is to get a model for each part of the document report, transaction, LogLines. I do not seem to understand how to do that.
Report Model (Works Fine)
class Report
include Mongoid::Document
field :ReportName, type: String
field :TestName, type: String
field :Transactions, type: Array
field :ReportDurationMS, type: String
embeds_many :transactions
end
Transaction Model
class Transaction
include Mongoid::Document
field :colId, type: String
field :InfoPlate, type: String
field :rowId, type: String
field :sortDate, type: String
field :transactionDate, type: String
field :description, type: String
field :startDate, type: String
field :startDateMS, type: Integer
field :endDate, type: String
field :endDateMS, type: Integer
field :finalEndDate, type: String
field :completeDuration, type: String
field :completeDurationMS, type: Integer
field :feedProcessingDuration, type: String
field :feedProcessingDurationMS, type: Integer
field :logLines, type: Array
embedded_in :report, :inverse_of => :transactions
end
Report Controller (Index Method) Debug logger is just there while I hack around
def index
#reports = Report.all
Rails.logger.info("********* #{#reports.inspect} ***********")
end
Transaction Controller (This is what I can't get to return a transaction as a model) I get a transaction back from #report.transactions but its just a string of json as opposed to a ruby model. Or at least I can't call anything like #transaction.colId. Just returns no such method. Transactions is an array there are many so I did try transactions.first.InfoPlate but still to me it seems Rails just seems the transaction that comes back as a string of JSON not an object.?
class TransactionsController < ApplicationController
before_action :set_transaction, only: [:show, :edit, :update, :destroy]
def index
#report = Report.find(params[:report_id])
#transaction = #report.transactions
Rails.logger.info("********* report #{#report.inspect} ***********")
#transactions = #report.transactions
Rails.logger.info("********* transaction #{#transactions.inspect} ***********")
end
My route
resources :reports do
resources :transactions
end
The above post made me go back in and match all my case and that seems to be working.

Why multi-field mapping is not working with tire gem for elasticsearch?

I'm using elastic search to enhance search capabilities in my app. Search is working perfectly, however sorting is not for fields with multiple words.
When I try to sort the search by log 'message', I was getting the error:
"Can't sort on string types with more than one value per doc, or more than one token per field"
I googled the error and find out that I can use multi-fields mapping on the :message field (one analyzed and the other one not) to sort them. So I did this:
class Log < ActiveRecord::Base
include Tire::Model::Search
include Tire::Model::Callbacks
tire.mapping do
indexes :id, index: :not_analyzed
indexes :source, type: 'string'
indexes :level, type: 'string'
indexes :created_at, :type => 'date', :include_in_all => false
indexes :updated_at, :type => 'date', :include_in_all => false
indexes :message, type: 'multi_field', fields: {
analyzed: {type: 'string', index: 'analyzed'},
message: {type: 'string', index: :not_analyzed}
}
indexes :domain, type: 'keyword'
end
end
But, for some reason is not passing this mapping to ES.
rails console
Log.index.delete #=> true
Log.index.create #=> 200 : {"ok":true,"acknowledged":true}
Log.index.import Log.all #=> 200 : {"took":243,"items":[{"index":{"_index":"logs","_type":"log","_id":"5 ... ...
# Index mapping for :message is not the multi-field
# as I created in the Log model... why?
Log.index.mapping
=> {"log"=>
{"properties"=>
{"created_at"=>{"type"=>"date", "format"=>"dateOptionalTime"},
"id"=>{"type"=>"long"},
"level"=>{"type"=>"string"},
"message"=>{"type"=>"string"},
"source"=>{"type"=>"string"},
"updated_at"=>{"type"=>"date", "format"=>"dateOptionalTime"}}}}
# However if I do a Log.mapping I can see the multi-field
# how I can fix that and pass the mapping correctly to ES?
Log.mapping
=> {:id=>{:index=>:not_analyzed, :type=>"string"},
:source=>{:type=>"string"},
:level=>{:type=>"string"},
:created_at=>{:type=>"date", :include_in_all=>false},
:updated_at=>{:type=>"date", :include_in_all=>false},
:message=>
{:type=>"multi_field",
:fields=>
{:message=>{:type=>"string", :index=>"analyzed"},
:untouched=>{:type=>"string", :index=>:not_analyzed}}},
:domain=>{:type=>"keyword"}}
So, Log.index.mapping is the current mapping in ES which doesn't contain the multi-field that I created. Am I missing something? and why the multi-field is shown in Log.mapping but not in Log.index.mapping?
I have changed the workflow from:
Log.index.delete; Log.index.create; Log.import
to
Log.index.delete; Log.create_elasticsearch_index; Log.import
The MyModel.create_elasticsearch_index creates the index with proper mapping from model definition. See Tire's issue #613.

How does save work in mongoID

There is a Object and embedded SubObject
class Object
include Mongoid::Document
embeds_many :sub_objects
end
class SubObject
include Mongoid::Document
field :str1,:type => String
field :ind1,:type => Integer
embedded_in :object
end
Console output
irb(main):060:0> obj = Object.first
=> #<Object _id: 4fd5ed971d41c8252c001f49, ..............>
irb(main):061:0> obj.sub_objects.size
=> 24000
irb(main):062:0> obj.save
=> true
Here is interesting thing happens.
Mongoid does not actually save the object because the object was not changed.
I.e. there is no call to mongodb.
But the save operation itself takes 18 (!!!) seconds.
Can anyone explain me what is happening and how can I avoid it?
Thanks.
this should do it:
obj.save if !obj.persisted? || obj.changed? # only save if new record, or something changed

Mongodb , rails modify non-array - debug kind_of? Array >> true

I've been trying to add to an array (or what ruby is saying is an array), but keep getting an error from mongo which says
Cannot apply $addToSet modifier to non-array
when I try to run
User.collection.update({'id'=> current.id},{'$addToSet'=>{ 'following' => current.id}})
User.collection.update({'id'=> user.id},{'$addToSet'=>{ 'following' => user.id}})
or the mongomapper version
User.push_uniq(current.id, :following => user.id)
User.push_uniq(user.id, :followers => current.id)
When I output
<%= debug #user.following.kind_of? Array %>
returns true
However, when running
db.users.find()
directly agains mongo, I get
{ "_id" : ObjectId("4c4a196f15a79004e0000007"), "email" : "test#test.com", "foll
owers" : null, "following" : null, "password_hash" : "98f2188de42bce1554d08fbc81
d5c99a2c234933", "password_salt" : "25d80a83cfe3d126cdbe9fec2b731ab9ea57c3b8", "
username" : "test" }
I would have expected following and followers to be [], not null.
When I output debug #user.followers, rails shows --- []
My model to create the user is
key :username, :type => String
key :email, :type => String
key :password_hash, :type => String
key :password_salt, :type => String
key :followers, :type => Array
key :following, :type => Array
The error leads me to believe that the user.followers is being found, but can't be updated.
When I change
User.push_uniq(current.id, :testing => user.id)
I don't get an error, so I think i have that part right.
Any suggestions?
This works for be in 0.8 when declaring the key using key :following, Array instead of key :following, :type => Array.
I tried both push_uniq and collection.update, and didn't get errors on either one. In your collection.update example, you do need to use _id: value instead of id: value since that command is being passed to mongo directly.
Turns out this is a bit of an inconsistency with defining keys in mongomapper.
Don't use the :type => qualifier with Arrays.
I deleted the entire collection, removed :type, and recreated everything and now it works.

Resources