rspec - why does this array key comparison fail? - ruby-on-rails

Failure/Error: #group.attributes.keys.should include (Group.first.attributes.keys)
expected
["id", "duration", "frequency", "period", "group_size", "location", "service", "area_of_need", "created_at", "updated_at", "therapist_id", "start_date", "end_date", "student_id", "adhoc"]
to include
["id", "duration", "frequency", "period", "group_size", "location", "service", "area_of_need", "created_at", "updated_at", "therapist_id", "start_date", "end_date", "student_id", "adhoc"]
Test:
#group.attributes.keys.should include (Group.first.attributes.keys)

Because a.should includes(b) asserts that a.include? b is true andinclude? checks to see if an array's elements includes an object, not whether one array equals another
[1].include? [1]
=> false
[1].include? 1
=> true
[[1]].include? [1]
=> true

Te answer was that the hash comparison fails on Ubuntu but works on Mac's.
My workaround is:
i=0
while i < #group.attributes.count
assert_equal #group.attributes[i], Group.first.attributes[i]
i+= 1
end
# Comparing field by field as ruby hash comparison isn't working right -
# but only on Ubuntu!

Related

postgreSQL date records only persisting up to a certain point in time in Rails

I am seeding some simple data in my rails program that is using a postgres database.
Currently, it is only persisting certain dates to the database. Other times, it is showing up as null in my API, which is very odd. I will post a picture of my database, and the seeded data, as well as my JSON API.
Here is my table:
create_table "pickup_deliveries", force: :cascade do |t|
t.date "pickup_date"
t.text "pickup_location"
t.money "rate", scale: 2
t.date "delivery_date"
t.text "delivery_location"
t.boolean "local"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "loaded_miles", default: 0
t.integer "deadhead_miles", default: 0
end
Here is my seeded data:
PickupDelivery.create(:pickup_date => '05-10-2019', :pickup_location => 'Kansas City, MO', :rate => '550.00', :delivery_date => '05-11-2019', :delivery_location => 'Wichita, KS', :local => false, :loaded_miles => '550', :deadhead_miles =>'230');
PickupDelivery.create(:pickup_date => '05-20-2019', :pickup_location => 'Kansas City, MO', :rate => '550.00', :delivery_date => '05-25-2019', :delivery_location => 'Wichita, KS', :local => false, :loaded_miles => '550', :deadhead_miles =>'230');
Here is the persisted data in my JSON API:
[
{
id: 1,
pickup_date: "2019-10-05",
pickup_location: "Kansas City, MO",
rate: "550.0",
delivery_date: "2019-11-05",
delivery_location: "Wichita, KS",
local: false,
created_at: "2019-05-09T16:14:35.312Z",
updated_at: "2019-05-09T16:14:35.312Z",
loaded_miles: 550,
deadhead_miles: 230
},
{
id: 2,
pickup_date: null,
pickup_location: "Kansas City, MO",
rate: "550.0",
delivery_date: null,
delivery_location: "Wichita, KS",
local: false,
created_at: "2019-05-09T16:14:35.319Z",
updated_at: "2019-05-09T16:14:35.319Z",
loaded_miles: 550,
deadhead_miles: 230
}
]
As you can see, the dates were both inputted in the same format, but only one came out as intended while the other came out as null
Thanks for reading.
The reason is that you are passing an invalid format in the second record
# Record 1
:delivery_date => '05-11-2019' # dd-mm-yyyy
# to
delivery_date: "2019-11-05"
# Record 2
:delivery_date => '05-25-2019' # dd-mm-yyyy
# Invalud since there is no month 25
so it becomes nil
This date is being parsed as dd-mm-yyyy
The date you are passing in the second record is invalid due to the month
I suggest you pass the date in this format 'dd-mm-yyyy' - '20-05-2019'
NOTE: Even in your first record the date in being parsed as 05 the day, 11 as the month and 2019 as the year

Ruby on Rails decimal comparison stopped working

I have been using a state object in the database that keeps track of what seed data has been loaded into it. The structure of the table is:
create_table "toolkit_states", force: :cascade do |t|
t.boolean "signups", default: true
t.decimal "database_version", precision: 5, scale: 2
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
The seeds.rb file checks the database_version and runs blocks of code and then sets the database_version after running the block. It has worked fine from versions 0.1 up to 0.55.
I added a new block of seed data. To run that block the database_version is checked and it should be 0.56. The following comparison does not work:
if state.database_version == 0.56
For some reason, the number 0.56 cannot be evaluated for equality with the value stored in the database. It has worked on all the values up to 0.56.
Here is a rails console session:
irb(main):001:0> state = ToolkitState.first
ToolkitState Load (0.4ms) SELECT "toolkit_states".* FROM "toolkit_states" ORDER BY "toolkit_states"."id" ASC LIMIT $1 [["LIMIT", 1]]
=> #<ToolkitState id: 1, signups: false, database_version: 0.56e0, created_at: "2018-12-27 17:04:50", updated_at: "2018-12-27 17:04:56">
irb(main):002:0> state.database_version == 0.56
=> false
irb(main):003:0> state.database_version == 0.56e0
=> false
irb(main):004:0> state.database_version == 0.56.to_f
=> false
irb(main):005:0> state.database_version.to_f == 0.56
=> true
When I convert the value with a "to_f", the comparison works. My problem is that it as worked well without this conversion up to the value, 0.56
It occurs because state.database_version is an instance of BigDecimal class. This article explain why it is BigDecimal.
Look at this example:
BigDecimal('0.56e0')
=> 0.56e0
irb(main):008:0> BigDecimal('0.56e0') == 0.56
=> false
irb(main):009:0> BigDecimal('0.56e0').to_f
=> 0.56
As you can see 0.56e0 after transformation to float type becomes 0.56 and your comparison returns true.
Nate explained more briefly why it's happening in this comment.
irb(main):001:0> c = BigDecimal('0.56e0')
=> 0.56e0
irb(main):002:0> c == 0.56
=> false
irb(main):003:0> c = BigDecimal('0.55e0')
=> 0.55e0
irb(main):004:0> c == 0.55
=> true
Works for 0.55 and not for 0.56 Rails bug?

Rails migration adds column to schema but not postgresql database

I am adding a column to an existing table in my DB. The migration created here:
// ♥ rails g migration AddFieldToRecipes
Running via Spring preloader in process 80952
invoke active_record
create db/migrate/20180628220935_add_field_to_recipes.rb
Edited here:
class AddFieldToRecipes < ActiveRecord::Migration[5.2]
def change
add_column :recipes, :cooked, :boolean, null: false, default: false
end
end
Is run here:
// ♥ rails db:migrate
== 20180628220935 AddFieldToRecipes: migrating
================================
-- add_column(:recipes, :cooked, :boolean, {:null=>false,
:default=>false})
-> 0.0079s
== 20180628220935 AddFieldToRecipes: migrated (0.0080s)
=======================
Does change the schema:
create_table "recipes", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "cooked", default: false, null: false
end
And the ActiveRecord sees the change when I run:
ActiveRecord::Base.connection.columns("recipes")
=> [#<ActiveRecord::ConnectionAdapters::PostgreSQLColumn:0x00007f8b69f91018
#collation=nil,
#comment=nil,
#default=nil,
#default_function="nextval('recipes_id_seq'::regclass)",
#max_identifier_length=63,
#name="id",
#null=false,
#sql_type_metadata=
#<ActiveRecord::ConnectionAdapters::SqlTypeMetadata:0x00007f8b69f912c0 #limit=8, #precision=nil, #scale=nil, #sql_type="bigint", #type=:integer>,
#table_name="recipes">,
#<ActiveRecord::ConnectionAdapters::PostgreSQLColumn:0x00007f8b69f905c8
#collation=nil,
#comment=nil,
#default=nil,
#default_function=nil,
#max_identifier_length=63,
#name="created_at",
#null=false,
#sql_type_metadata=
#<ActiveRecord::ConnectionAdapters::SqlTypeMetadata:0x00007f8b69f90960
#limit=nil,
#precision=nil,
#scale=nil,
#sql_type="timestamp without time zone",
#type=:datetime>,
#table_name="recipes">,
#<ActiveRecord::ConnectionAdapters::PostgreSQLColumn:0x00007f8b6ad6f860
#collation=nil,
#comment=nil,
#default=nil,
#default_function=nil,
#max_identifier_length=63,
#name="updated_at",
#null=false,
#sql_type_metadata=
#<ActiveRecord::ConnectionAdapters::SqlTypeMetadata:0x00007f8b6ad6fc48
#limit=nil,
#precision=nil,
#scale=nil,
#sql_type="timestamp without time zone",
#type=:datetime>,
#table_name="recipes">,
#<ActiveRecord::ConnectionAdapters::PostgreSQLColumn:0x00007f8b6ad6edc0
#collation=nil,
#comment=nil,
#default="false",
#default_function=nil,
#max_identifier_length=63,
#name="cooked",
#null=false,
#sql_type_metadata=
#<ActiveRecord::ConnectionAdapters::SqlTypeMetadata:0x00007f8b6ad6ef78 #limit=nil, #precision=nil, #scale=nil, #sql_type="boolean", #type=:boolean>,
#table_name="recipes">]
But is not reflected on the model when in the console (or in the app):
[1] pry(main)> Recipe.columns.map { |c| c.name }
=> ["id", "title", "description", "author", "user_id", "type", "created_at", "updated_at"]
So I tried resetting the column information:
[2] pry(main)> Recipe.reset_column_information
=> {true=>#<Concurrent::Map:0x007f8b69681cc0 entries=0 default_proc=nil>, false=>#<Concurrent::Map:0x007f8b69681c20 entries=0 default_proc=nil>}
Still no change:
[3] pry(main)> Recipe.columns.map { |c| c.name }
=> ["id", "title", "description", "author", "user_id", "type", "created_at", "updated_at"]
Based on many (many) questions/answers found here (also another of the same exact question with no answer), I have rolled back the migration and reran it -- same. Rolled back, and reloaded the schema, reran -- same. Since it's dev, I also dropped the DB, created, migrated -- same.
What am I missing? I just want to be able to have recipe.cooked show me true or false.

Load CSV with headers into rails

I've reviewed many, many responses and still unable to preload rails 5 table with csv file. This is my first attempt to load data from rails console. Please help!
csv file formats liket this with CSV.foreach()
["model_id", "model_make_id", "model_name", "model_trim", "model_year", "model_make_display_name"]
["44328", "acura", "MDX", nil, "2011", "Acura"]
["44331", "acura", "RDX", nil, "2011", "Acura"]
["44332", "acura", "RDX", "SH-AWD", "2011", "Acura"]
["44334", "acura", "RL", nil, "2011", "Acura"]
["44337", "acura", "TL", nil, "2011", "Acura"]
.rb file code
require 'csv'
CSV.foreach('./tmp/cq_sample.csv', :headers => true) do |row|
record = Cqref.new(
:model_id => row[0], # first column of csv file
:model_make_id => row[1], # second column
:model_name => row[2], # third
:model_trim => row[3], # fourth
:model_year => row[4], # fifth
:model_make_display_name => row[5] # sixth
)
record.save
end
Schema
create_table "cqrefs", force: :cascade do |t|
t.string "model_id"
t.string "model_make_id"
t.string "model_name"
t.string "model_trim"
t.string "model_year"
t.string "model_make_display_name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
Error Mesage Extract:
require './tmp/importcsv'
ActiveRecord::DangerousAttributeError: model_name is defined by Active Record. Check to make sure that you don't have an attribute or method with the same name.
from /usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.2/lib/active_record/attribute_methods.rb:91:in `instance_method_already_implemented?'
from /usr/local/rvm/gems/ruby-2.3.0/gems/activemodel-5.0.2/lib/active_model/attribute_methods.rb:288:in `block in define_attribute_method'

Unset operation failing for MongoMapper model, cannot delete / remove key from model

We're on mongodb 2.0.0, mongo gem 1.4.1, mongo_mapper 0.9.2, rails 3.0.6.
We love MongoMapper, but we need helping resolving one nasty issue: we have a key carried over from some testing, but invoking obj.unset fails to do anything.
Specifically, we are trying to remove an "id" key (not "_id") because it's causing MM to treat obj.id as different from obj._id, which we don't want.
After clearing out the database, we ran these commands from a controller which does nothing else: (We also tried running the same code from the rails console, but it also fails.)
logger.info "#{Game.keys.keys.inspect}"
Game.unset({}, :id)
logger.info "#{Game.keys.keys.inspect}"
Game.unset(:id)
logger.info "#{Game.keys.keys.inspect}"
Output:
["jackpot", "players", "created_at", "puzzles", "ended_at", "player_index", "updated_at", "log", "_id", "id", "join_code", "puzzle_index"]
["jackpot", "players", "created_at", "puzzles", "ended_at", "player_index", "updated_at", "log", "_id", "id", "join_code", "puzzle_index"]
["jackpot", "players", "created_at", "puzzles", "ended_at", "player_index", "updated_at", "log", "_id", "id", "join_code", "puzzle_index"]
Current keys defined in our Game model:
key :players, Array, :default => []
key :player_index, Integer, :default => 0
key :puzzles, Array, :default => []
key :puzzle_index, Integer, :default => 0
key :join_code, String, :default => nil
key :jackpot, Integer, :default => 0
key :log, Array, :default => []
key :created_at, Time
key :updated_at, Time
key :ended_at, Time, :default => nil
Help?
Thanks!
It pains us to post the answer since this solidifies our status as "morons, idiots, fools, noobs, Jay Leno fans," but in case anyone else bumps into the same issue: while our model directory was clean in the dev environment, the model dir in the production environment contained old test files ... which contained an old model with the "id" key.
Obviously, removing the old files and the old models solved everything, though we're left with staggering bruises to our egos and to our heads (from excessive banging against the walls).

Resources