Rails Digest::UUID v5 (vs) Postgresql uuid-ossp v5 - ruby-on-rails

I'm getting different V5 UUIDs when generating with Rails Digest::UUID and Postgresql uuid-ossp.
Rails:
[58] pry(main)> Digest::UUID.uuid_v5('e90bf6ab-f698-4faa-9d0f-810917dea53a', 'e90bf6ab-f698-4faa-9d0f-810917dea53a')
=> "db68e7ad-332a-57a7-9638-a507f76ded93"
Postgresql uuid-ossp:
select uuid_generate_v5('e90bf6ab-f698-4faa-9d0f-810917dea53a', 'e90bf6ab-f698-4faa-9d0f-810917dea53a');
uuid_generate_v5
--------------------------------------
6c569b95-a6fe-5553-a6f5-cd871ab30178
What would be the reason? I thought both should generate the same UUID when the input is the same, but it is different!

It's not an answer to the question about why Rails produces a different result, but if you want to produce v5 UUID in your Ruby code, you could use uuidtools. It returns the same result as PSQL:
~ pry
[1] pry(main)> require 'uuidtools'
=> true
[2] pry(main)> UUIDTools::UUID.sha1_create(UUIDTools::UUID.parse('e90bf6ab-f698-4faa-9d0f-810917dea53a'), 'e90bf6ab-f698-4faa-9d0f-810917dea53a')
=> #<UUID:0x3fe09ea60dd8 UUID:6c569b95-a6fe-5553-a6f5-cd871ab30178>
[3] pry(main)>

It seems that a patch is proposed so that working string-representation of namespaces can be enabled explicitly
The new behavior will be enabled by setting the config.active_support.use_rfc4122_namespaced_uuids option to
true.
but, the patch is very recent and it could be still under test. People can be afraid it breaks things. Check
https://github.com/rails/rails/issues/37681
https://github.com/rails/rails/pull/37682/files
Meanwhile, a workaround is to pack the namespace string
ns=n.scan(/(\h{8})-(\h{4})-(\h{4})-(\h{4})-(\h{4})(\h{8})/).flatten.map { |s| s.to_i(16) }.pack("NnnnnN")
In your example
irb(main):037:0> n='e90bf6ab-f698-4faa-9d0f-810917dea53a'
=> "e90bf6ab-f698-4faa-9d0f-810917dea53a"
irb(main):038:0> ns=n.scan(/(\h{8})-(\h{4})-(\h{4})-(\h{4})-(\h{4})(\h{8})/).flatten.map { |s| s.to_i(16) }.pack("NnnnnN")
=> "\xE9\v\xF6\xAB\xF6\x98O\xAA\x9D\x0F\x81\t\x17\xDE\xA5:"
irb(main):039:0> puts Digest::UUID.uuid_v5(ns, 'e90bf6ab-f698-4faa-9d0f-810917dea53a')
6c569b95-a6fe-5553-a6f5-cd871ab30178

Related

can Ruby (or Rails) class loses its object_id during single thread execution?

I've spotted strange bug.
When running a db:seed script in my Ubuntu Laptop MRI 2.6.3 Ruby everything goes well.
But when I trigger same db:seed script under Docker container (MRI 2.6.3, Rails 5.2.3) it seems one particular class loses its object ID:
[47] pry(#<Maintenance::SeedDataService>)> school
=> #<School id:1 public_uid:4ca01880 title:Dummy School>
[48] pry(#<Maintenance::SeedDataService>)> school.class
=> School(id: integer, title: string, .......)
[49] pry(#<Maintenance::SeedDataService>)> school.class.object_id
=> 70060822718420
[50] pry(#<Maintenance::SeedDataService>)>
[51] pry(#<Maintenance::SeedDataService>)>
[52] pry(#<Maintenance::SeedDataService>)> School.object_id
=> 70060817034380
[53] pry(#<Maintenance::SeedDataService>)> school.class == School
=> false
[54] pry(#<Maintenance::SeedDataService>)>
So basically school = School.last; school.class != School
or other words School != School
I've triple checked there is no other definitions of class School in code base or related Gems
Script is executed in single thread (as rake db:seed and nothing is reloading any classes. So best to my knowledge Ruby class object should never lose its id (as it's acting as Singleton)
this is like if 1 loses its object id and suddenly 1 != 1
Am I missing somethnig here or this is a Ruby bug inside Docker container ?

String start with # return with backslash in rails console in some case

In console of rails 4.2.7, I have the following test:
[45] pry(main)> '#$'
=> "\#$"
[46] pry(main)> '##'
=> "\##"
[47] pry(main)> '#!'
=> "#!"
[48] pry(main)> '#ab'
=> "#ab"
It seems rails will only put a "\" before the string when there is an # or $ after #.
The problem leads me to this test is that I have a erb file that render a data attribute with an array of json:
data-xx="<%= [{xx: '#$', yy: 'yy'}.to_json, {zz: 'zzz'}.to_json] %>"
Then in chrome console, it will give the unexpected result as
$("#entry_show_modal_template").data('xx')
"["{\"xx\":\"\#$\",\"yy\":\"yy\"}", "{\"zz\":\"zzz\"}"]"
And when I change xx value from #! or some other string, the result will be ok as an array
$("#entry_show_modal_template").data('xx')
["{"xx":"#!","yy":"yy"}", "{"zz":"zzz"}"]
Does someone know if it is true and why it has such difference?
And it there any way to tackle this problem?
This is not true.
In '#{...}' hash will also be escaped. This is done to prevent recursive/implicit string interpolation.
Look:
$a = 'hello'
"#$a"
#⇒ "hello"
The problem is already solved by ruby for you. Just use the produced string as is and don’t be fooled by the way it is printed out in console.
"\#$".length
#⇒ 2
"\#$" == '#$'
#⇒ true
"\#$"[0]
#⇒ "#"
#mudasobwa's explaination is correct
According to your situation you should try in this way
===> In rails console
json_values = [{xx: '#$', yy: 'yy'}, {zz: 'zzz'}].to_json
===> In chrome console
result = JSON.parse(json_values)
you will get expected array, its just ruby technique to handle string interpolation thing

ActiveRecord query fails in binding.pry

I'm using binding.pry in a test environment but getting some very peculiar results:
[4] pry(#<RentalItem>)> self.charged_amounts
=> [#<ChargedAmount id: 1, type_of_amount:"rental", charge_id:1, rental_item_id:1>, #<ChargedAmount id: 2, ...>]
[5] pry(#<RentalItem>)> self.charged_amounts.where(type_of_amount:"rental")
=> []
[6] pry(#<RentalItem>)> self.charged_amounts.where(charge_id:1)
=> []
[7] pry(#<RentalItem>)> self.charged_amounts.where(rental_item_id:1)
=> []
Trying to understand and get some ideas in terms of why the behavior above might be happening. I.e., give me a starting point to debug.
Thanks
That's because of how rails handles transactional fixtures. Basically, records are deleted between tests. You can read more about it here Transactional Fixtures in Rails

Wice_Grid CSV export not working - Uninitialized constant CSV::Writer

I "inherited" a rails aplication running with ruby 1.8.7 in development.
I have a wice_grid table which I'm trying to export in CSV and in development all goes perfect.
When I push it to production, i get the following error:
uninitialized constant CSV::Writer
The production machine is running Ruby 1.9.1 and from what I read, I suppose the problem comes from there.
I've tried to put:
required 'csv'
In the controller or the model, but nothing happens, development works, production does not.
Here is the controller code:
def index
require 'csv'
#service_requests = initialize_grid(ServiceRequest,
:name => "solicitudes",
:order => "created_at" ,
:order_direction => 'desc',
:include => [:user, :service],
:enable_export_to_csv => true,
:csv_file_name => 'Listado de Solicitudes'
)
export_grid_if_requested('solicitudes' => 'service_requests') do
#Si se pulsa en exportar se exportan todos las celdas de la tabla seleccionada (con filtros aplicados)
end
end
Here is the part of the view, which calls a partial:
<%= render :partial => 'service_requests' %>
Here is the partial, cropped for making the question not too long:
<%= grid(#service_requests, :show_filters => :always) do |service_request|
[...]
service_request.column :column_name => 'Nombre' , :attribute_name => 'name', :model_class => User do |sr|
sr.user.name
end
service_request.column :column_name => 'Apellidos' , :attribute_name => 'lastName' , :model_class => User do |sr|
sr.user.lastName
end
[...]
end %>
I read this thread but didnt help me much: write csv in ruby 1.9 and CSV::Writer
Thank you all in advance!
Somewhere, that you haven't posted, you are referencing CSV::Writer. This works locally because you're using Ruby 1.8.7, but your production server is using Ruby 1.9.1. CSV::Writer was deprecated with Ruby 1.9.
From the the docs:
# * The old CSV's Reader and Writer classes have been dropped.
Step one is to upgrade your local Ruby to the same version as the server. This will give you the same error locally, which should go away once you find and remove that CSV::Writer.
The CSV docs give examples of how to use the current CSV class to accomplish what CSV::Writer used to do. Here's an example:
# == Writing
#
# === To a File
#
# CSV.open("path/to/file.csv", "wb") do |csv|
# csv << ["row", "of", "CSV", "data"]
# csv << ["another", "row"]
# # ...
# end
Upgrading Ruby will probably raise other errors. But Ruby 1.8.7 was retired in 2013 so these are problems you're going to want to fix now rather than later.
Good luck!

autoload_paths not aware of namespace?

In app/services, I have some classes, as Notification::Finder and Notification::Builder.
They are placed as app/services/notification/builder.rb and app/services/notification/finder.rb.
There is also the Notification class as a model, at app/models/notification.rb
The autoload_path is configurated as in config.autoload_paths += %W(#{config.root}/app/services)
When I try to load Finder, it works:
Loading development environment (Rails 3.2.9)
[1] pry(main)> Notification::Finder
=> Notification::Finder
But when I try the Builder, I get a problem with the rails autoloading:
Loading development environment (Rails 3.2.9)
[1] pry(main)> Notification::Builder
=> ActiveRecord::Associations::Builder
It just ignores the namespace I've used when the constant name (Builder) has already been defined by other namespace, and gets the ActiveRecord::Associations::Builder instead.
Is this the expected behavior, or a rails bug?
Going more detailed, the const_missing method at activesupport/dependencies.rb receives a const_name 'Builder', and nesting.inspect => 'nil'.
Curious that when I use constantize, it resolves as expected:
Loading development environment (Rails 3.2.9)
[1] pry(main)> 'Notification::Builder'.constantize
=> Notification::Builder
( Rails issue at github: https://github.com/rails/rails/issues/8726 )
ActiveRecord::Associations::Builder is a module in Rails. If you have a Notification::Builder, you can ask it its class:
>> Notification::Builder
=> ActiveRecord::Associations::Builder
>> Notification::Builder.class
=> Module
>> Notification::Builder.ancestors
=> [ActiveRecord::Associations::Builder]
Is this expected behavior?
Yes
OK, so... what choices do you have?
You can use a different term than Builder. Like Factory. or Notification::NotificationBuilder
More info:
* http://www.rubydoc.info/docs/rails/3.1.1/ActiveRecord/Associations/Builder/Association
* http://apidock.com/rails/ActiveRecord/Associations/Builder
This problem exists because you are using an ActiveRecord model as a namespace. I created a gist with some experimentation until I saw the root cause.
ActiveRecord models include the ActiveRecord::Associations module. Since you can get to a constant when including a module the Builder constant defined within Associations is now also reachable through the AR model. You will get this behavior with every class defined in the modules, which are included into an AR model:
1.9.3-p194 :010 > Post.ancestors
=> [Post(id: integer, title: string, published_at: datetime, created_at: datetime, updated_at: datetime), Post::GeneratedFeatureMethods, #<Module:0x007fec74dc33a0>, ActiveRecord::Base, ActiveRecord::Core, ActiveRecord::Store, ActiveRecord::Serialization, ActiveModel::Serializers::Xml, ActiveModel::Serializers::JSON, ActiveModel::Serialization, ActiveRecord::Reflection, ActiveRecord::Transactions, ActiveRecord::Aggregations, ActiveRecord::NestedAttributes, ActiveRecord::AutosaveAssociation, ActiveModel::SecurePassword, ActiveRecord::Associations, ActiveRecord::Timestamp, ActiveModel::Validations::Callbacks, ActiveRecord::Callbacks, ActiveRecord::AttributeMethods::Serialization, ActiveRecord::AttributeMethods::Dirty, ActiveModel::Dirty, ActiveRecord::AttributeMethods::TimeZoneConversion, ActiveRecord::AttributeMethods::PrimaryKey, ActiveRecord::AttributeMethods::Query, ActiveRecord::AttributeMethods::BeforeTypeCast, ActiveRecord::AttributeMethods::Write, ActiveRecord::AttributeMethods::Read, ActiveRecord::AttributeMethods, ActiveModel::AttributeMethods, ActiveRecord::Locking::Pessimistic, ActiveRecord::Locking::Optimistic, ActiveRecord::CounterCache, ActiveRecord::Validations, ActiveModel::Validations::HelperMethods, ActiveSupport::Callbacks, ActiveModel::Validations, ActiveRecord::Integration, ActiveModel::Conversion, ActiveRecord::AttributeAssignment, ActiveModel::ForbiddenAttributesProtection, ActiveModel::DeprecatedMassAssignmentSecurity, ActiveRecord::Sanitization, ActiveRecord::Scoping::Named, ActiveRecord::Scoping::Default, ActiveRecord::Scoping, ActiveRecord::Inheritance, ActiveRecord::ModelSchema, ActiveRecord::ReadonlyAttributes, ActiveRecord::Persistence, Object, PP::ObjectMixin, ActiveSupport::Dependencies::Loadable, V8::Conversion::Object, JSON::Ext::Generator::GeneratorMethods::Object, Kernel, BasicObject]
A possible solution is to use a module as a namespace. For example module Notifications.

Resources