Create model instances from array - ruby-on-rails

I have a 2D array of data and need to create new Measurement model instances. What is best way to do that?
Simplified array:
=> [{"Date"=>"02/03/2017 11:46:11",
"Location"=>"Sissach",
"Serial Number"=>460631,
"Air Humiditiy (%)"=>27.5,
"Air Temperature (°C)"=>17.4},
{"Date"=>"02/03/2017 11:46:21",
"Location"=>"Sissach",
"Serial Number"=>460632,
"Air Humiditiy (%)"=>27.2,
"Air Temperature (°C)"=>17.7}}]
Any gem for auto convert data to database type of data ? Thanks for your time.

Considering your model Measurement has the next structure:
Measurement(
id: integer,
date: datetime,
location: string,
serial_number: integer,
humidity: float,
temperature: float,
created_at: datetime,
updated_at: datetime
)
You can easily iterate over your array of hashes and on each element, create a new Measurement record, like:
[
{ "date"=>"02/03/2017 11:46:11", "location"=>"Sissach", "serial_number"=>460631, "humidity"=>27.5, "temperature"=>17.4 },
{ "date"=>"02/03/2017 11:46:21", "location"=>"Sissach", "serial_number"=>460632, "humidity"=>27.2, "temperature"=>17.7 }
].each do |measurement|
Measurement.create(
location: measurement['location'],
serial_number: measurement['serial_number'],
date: measurement['date'],
humidity: measurement['humidity'],
temperature: measurement['temperature']
)
end
Or as #7urkm3n pointed out, just by passing the array of hashes it would work the same way.
Consider the block in case you need to do any extra operation, or if you want to initialize first a model object and then check if the record trying to be saved has success.

Related

How to split an array of objects into subarrays depending on the field value in Rails and Mongodb

I want to get several arrays of objects aggregated by months (and years) in a their property value.
I have class Request like this:
class Request
include Mongoid::Document
include MongoidDocument::Updated
field :name, type: String
field :start_date, type: DateTime
#...
end
And I want the resulting array of multiple hashes with
{month: m_value, year: y_value, request: requests_with_m_value_as_month_and_y_value_as_year_in_start_date_field}
as element of array
Can someone help me with this?
You can use Aggregation Pipeline to get the data in the right shape back from MongoDB:
db.requests.aggregate([
{
$group: {
_id: {
year: {
$year: "$start_date"
},
month: {
$month: "$start_date"
}
},
requests: {
$push: "$$ROOT"
}
}
},
{
$project: {
_id: 0,
year: "$_id.year",
month: "$_id.month",
requests: "$requests"
}
}
])
Obviously, this is using just the REPL and you will have to translate it to the DSL provided by Mongoid. Based on what I could find it should be possible to just get the underlying collection and call aggregate on it:
Request.collection.aggregate([...])
Now you just need to take the query and convert it into something that Mongoid will accept. I think you just need to add a bunch of quotes around the object keys but I don't the environment set up to try that myself.

How to declare array inside array in yaml file

for example : rate:
{floor: '1', functionId: BDEB1,
baseRates: { baseRateAgreementLevel: baseRateAgreementLevel,name: LIBOR GBP 1 Month, value: 0.1}
}
Above rate is a array and baserate is another array which is inside rate array
Getting error "Cannot create property" while declaring array inside array in snake yaml file.
I'm guessing you meant to write:
rate:
floor: '1'
functionId: BDEB1
baseRates:
baseRateAgreementLevel: baseRateAgreementLevel
name: LIBOR GBP 1 Month
value: 0.1
Is this what you wanted? Take a look here for a json equivalent representation.

How to clear a complex Array and add an object to it in breeze?

So I have an object model declared as such:
helper.addComplexType
name: "Shift"
dataProperties:
end_time: "int"
start_time: "int"
earliest_in: "int"
earliest_out: "int"
latest_in: "int"
latest_out: "int"
in_early: "bool"
in_late: "bool"
out_early: "bool"
out_late: "bool"
helper.addType
name: 'DaySchedule'
apiVersion: 3
dataProperties:
uid: "uid"
employee_id: "int"
day: "string"
shifts:
complexType: "Shift"
hasMany: true
navigationProperties:
employee:
type: "Employee"
assoc: "DayScheduleEmployee"
key: ["employee_id"]
Now I have some code that changes one of these entities and then saves it back to the server...
shiftType = entityManager.metadataStore.getEntityType("Shift");
shift = shiftType.createInstance
start_time: moment(#start_time).unix()
end_time: moment(#end_time).unix()
schedule.shifts.splice -1
schedule.shifts.push shift
entityManager.saveChanges()
However, when I go to save this to the server, the "shift" on the other side ends up with no data values. This appears to be coming from, entityManager.helper.unwrapChangedValues, which is returning an empty object for this complex entity. Am I missing something in creating this complex object and then attaching it to the entity it is associated with?
EDIT: This seems to be a problem with the way breeze internally unwraps arrays.
https://github.com/Breeze/breeze.js/issues/4

MongoDB - Mongoid map reduce basic operation

I have just started with MongoDB and mongoid.
The biggest problem I'm having is understanding the map/reduce functionality to be able to do some very basic grouping and such.
Lets say I have model like this:
class Person
include Mongoid::Document
field :age, type: Integer
field :name
field :sdate
end
That model would produce objects like these:
#<Person _id: 9xzy0, age: 22, name: "Lucas", sdate: "2013-10-07">
#<Person _id: 9xzy2, age: 32, name: "Paul", sdate: "2013-10-07">
#<Person _id: 9xzy3, age: 23, name: "Tom", sdate: "2013-10-08">
#<Person _id: 9xzy4, age: 11, name: "Joe", sdate: "2013-10-08">
Could someone show how to use mongoid map reduce to get a collection of those objects grouped by the sdate field? And to get the sum of ages of those that share the same sdate field?
I'm aware of this: http://mongoid.org/en/mongoid/docs/querying.html#map_reduce
But somehow it would help to see that applied to a real example. Where does that code go, in the model I guess, is a scope needed, etc.
I can make a simple search with mongoid, get the array and manually construct anything I need but I guess map reduce is the way here. And I imagine these js functions mentioned on the mongoid page are feeded to the DB that makes those operations internally. Coming from active record these new concepts are a bit strange.
I'm on Rails 4.0, Ruby 1.9.3, Mongoid 4.0.0, MongoDB 2.4.6 on Heroku (mongolab) though I have locally 2.0 that I should update.
Thanks.
Taking the examples from http://mongoid.org/en/mongoid/docs/querying.html#map_reduce and adapting them to your situation and adding comments to explain.
map = %Q{
function() {
emit(this.sdate, { age: this.age, name : this. name });
// here "this" is the record that map
// is going to be executed on
}
}
reduce = %Q{
function(key, values) {
// this will be executed for every group that
// has the same sdate value
var result = { avg_of_ages: 0 };
var sum = 0; // sum of all ages
var totalnum = 0 // total number of people
values.forEach(function(value) {
sum += value.age;
});
result.avg_of_ages = sum/total // finding the average
return result;
}
}
results = Person.map_reduce(map, reduce) //You can access this as an array of maps
first_average = results[0].avg_of_ages
results.each do |result|
// do whatever you want with result
end
Though i would suggest you use Aggregation and not map reduce for such a simple operation. The way to do this is as follows :
results = Person.collection.aggregate([{"$group" => { "_id" => {"sdate" => "$sdate"},
"avg_of_ages"=> {"$avg" : "$age"}}}])
and the result will be almost identical with map reduced and you would have written a lot less code.

How do I count nil values in a model?

Assuming I have a model named "Person" & that person is defined by name, age, gender & race.
How do I iterate through the model to find out which values are nil?
For example:
name: peter
age: 34
gender: nil
race: nil
--Nil count: 2--
I understand I would have iterate through each field, do a +1 if value if nil & output the total value.
Thanks for any help or guidance!
If your instance is p then:
nils = p.attributes.values.select(&:nil?).count
will give you the number of nil attributes.

Resources