ActiveSupport encode_big_decimal_as_string - ruby-on-rails

I would like to use the ActiveSupport option encode_big_decimal_as_string on one of my models. Should I put it in the model? Do I call this method on a model instance? Do I place this somewhere in config? What is an ActiveSupport option and how could I use it?

Neither of these answers worked for me in Rails 4.0. Here is what works in Rails 4.0:
ActiveSupport::JSON::Encoding.encode_big_decimal_as_string = false
Add that line to your application config, like so:
# config/application.rb
...
module AppName
class Application < Rails::Application
...
ActiveSupport::JSON::Encoding.encode_big_decimal_as_string = false
...
end
end
As #tyler-nguyen said, this is being deprecated in Rails 4.1, and extracted into this gem: ActiveSupport JSON Encoder. Refer to the gem documentation for configuration in 4.1.

In Rails 4.0, you can set it in your application.rb as following:
config.active_support.encode_big_decimal_as_string = false
From Rails 4.1, the ActiveSupport.encode_big_decimal_as_string option is deprecated. The feature has been extracted to the activesupport-json_encoder gem.

I believe that you do it in the environment.rb file.
This is what should work. I don't have a way to test it right now.
Rails::Initializer.run do |config|
config.active_support.json.encode_big_decimal_as_string = true
end

Related

ActiveJob custom serializer - uninitialized constant NameError

I am trying to add a custom serializer to ActiveJob following the ActiveJob Rails Guide. I have the following class, originally in the file app/lib/money_serializer.rb,
class MoneySerializer < ActiveJob::Serializers::ObjectSerializer
# ...
end
And in config/application.rb
# ...
config.active_job.custom_serializers << MoneySerializer
# ...
I keep getting uninitialized constant MoneySerializer (NameError) which suggests to me that the Serializer is not being loaded on boot and tried placing it in different locations (including under config/initializers) without any luck.
What am I missing here? Where should I place an ActiveJob serializer?
Based on the discussion here, the issue is best solved as follows:
Rails.autoloaders.main.ignore(Rails.root.join("app/serializers"))
Dir[Rails.root.join("app/serializers/**/*.rb")].each { |f| require f }
Rails.application.config.active_job.custom_serializers << MoneySerializer
Update: In Rails 7, you can simply add the following to config/application.rb:
config.autoload_once_paths += Dir[Rails.root.join("app/serializers")]
If it helps anyone,
It seems to work when I put both the Serializer and the config in an initializer
class MoneySerializer < ActiveJob::Serializers::ObjectSerializer
# ...
end
config.active_job.custom_serializers << MoneySerializer
Feels very odd to have a class here. Any other suggestions?

Rails ActiveRecord mysql2 adapter, use PreparedStatement by default

PreparedStatement support for mysql2 has been already added in version 0.4.0, as per this link
As per following details in version 0.5.2 it still not uses prepared statement in all ORM queries internally:
Shipment.where(order_id: 78987898789)<br>
Shipment.where('order_id = ?', 56789876)
Mysql Log:
2019-03-10T13:20:01.722848Z 1072 Query SELECT `shipments`.* FROM `shipments` WHERE `shipments`.`order_id` = 78987898789<br>
2019-03-10T13:22:27.748687Z 1072 Query SELECT `shipments`.* FROM `shipments` WHERE (order_id = 56789876)
Is there a way to enable/disable it for all ORM queries? (Just like the PostgreSQL adapter ref). Does enabling it impact adversely on overall application performance?
If not, I haven't given a try yet but is it possible to achieve this using Sequel, and how complex is migrating an existing application from MySQL2 to Sequel.
ActiveRecord with Mysql2 < 5, doesn't support configurable parameter to enable prepared_statement
Code snippet from ActiveRecord 4.2.6
connection_adapters/mysql2_adapter.rb
module ConnectionAdapters
class Mysql2Adapter < AbstractMysqlAdapter
ADAPTER_NAME = 'Mysql2'.freeze
def initialize(connection, logger, connection_options, config)
super
#prepared_statements = false # No configurable param, default set to false
configure_connection
end
...
end
ActiveRecord with Mysql2 = 5.2.1 adapter support configurable parameter to enable prepared_statement
Code snippet from ActiveRecord 5.2.1
connection_adapters/mysql2_adapter.rb
module ConnectionAdapters
class Mysql2Adapter < AbstractMysqlAdapter
ADAPTER_NAME = "Mysql2".freeze
include MySQL::DatabaseStatements
def initialize(connection, logger, connection_options, config)
super
#prepared_statements = false unless config.key?(:prepared_statements)
configure_connection
end
...
end
So, in ActiveRecord 5.2.1, one can just add following line in database.yml to enable prepared_statements
prepared_statements: true

Rails 5 belongs_to_required_by_default doesn't work

I use Rails 5.0.0, but for some reason belongs_to_required_by_default doesn't work!
Application was created as new rails 5 app
class Visit < ApplicationRecord
belongs_to :user
end
> v = Visit.new
> v.valid? # => true
it works only with optional: false option
class Visit < ApplicationRecord
belongs_to :user, optional: false
end
> v = Visit.new
> v.valid? # => false
but why doesn't work configuration:
Rails.application.config.active_record.belongs_to_required_by_default = true
Where are you putting it? Have confirmed it works by putting it in development.rb as config.active_record.belongs_to_required_by_default = true inside Rails.application.configure do.
If you want it for everything you can put it in application.rb under class Application < Rails::Application as config.active_record.belongs_to_required_by_default = true
I believe you'll find putting it in the initializers directory will have problems with the loading order.
EDIT FOR RAILS 5.1: Everything should work well on a default Rails 5.1 application. Just make sure config.load_defaults 5.1 is in your application.rb (reference).
OLD ANSWER FOR RAILS 5.0.x
It look like this is due to some gems that monkey patch activerecord incorrectly, according to this Rails issue https://github.com/rails/rails/issues/23589.
You may want to comment/uncomment them out in your Gemfile until you find the culprit.
After this tedious process, I found that for my latest project it was the gems ahoy_matey, cancancan and delayed_job_active_record that caused the problem (at the time of writing).
In the meantime Ropeney's answer works, although not ideal since the "official rails way" is to declare config.active_record.belongs_to_required_by_default = true in the new_framework_default‌​s.rb initializer, not in application.rb.
In case anyone is still having this issue, you can upgrade to Rails 5.1 to fix it. In Rails 5.1, config/initializers/new_framework_defaults.rbhas been removed and replaced with the line config.load_defaults 5.1 in application.rb. This line includes
active_record.belongs_to_required_by_default = true and the other options that were in new_framework_defaults.rb.
module myApp
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails
version.
config.load_defaults 5.1
See the end of this thread for more details: https://github.com/rails/rails/issues/23589.
active_record.belongs_to_required_by_default = true only works for FactoryBot.create() method. you will still get validation error of child records not present where you have used FactoryBot.build() method. Any idea why this is not working for build()? any workaround?

Ruby - undefined method `extract_options!' : Array

While running following sample using TweetStream I am getting mentioned error.
tweets.rb
require 'tweetstream'
TweetStream.configure do |config|
config.consumer_key = '<CONSUMER KEY>'
config.consumer_secret = '<CONSUMER SECRET>'
config.oauth_token = '<OAUTH TOKEN>'
config.oauth_token_secret = '<OAUTH TOKEN SECRET'
config.auth_method = :oauth
end
TweetStream::Client.new.track('ruby') do |status|
puts "#{status.text}"
end
Error
$ ruby tweets.rb
/home/amit/.rvm/gems/ruby-1.9.3-p194/gems/tweetstream-2.3.0/lib/tweetstream/client.rb:96:in `track': undefined method `extract_options!' for ["ruby"]:Array (NoMethodError)
from tweets.rb:11:in `<main>'
https://github.com/intridea/tweetstream
Am I missing something?
Here's another solution: opening up Array class and defining extract_options! method on it.
Add the following code :
class Array
def extract_options!
last.is_a?(::Hash) ? pop : {}
end unless defined? Array.new.extract_options!
end
to the beginning of the tweets.rb file or to a separate file (which would
need to be required in the tweets.rb file).
extract_options! is ActiveSupport method. If it's not rails app you need to install it and include into script.
I am too late to answer but i think it'll be useful for ruby naive programmers like me.
To include ActiveSupport method like extract_options!, you need to include Active Support.
require 'active_support'
And if you want to include ruby gems then include rubygems too.
require 'rubygems'

Accessing rails_admin url helpers from Rspec files

I am using Rails 3.2, RailsAdmin 0.0.3, Rspec and Capybara.
I try to call RailsAdmin url helpers from my spec file as it is explained in the RailsAdmin wiki. rails_admin.new_path(:model_name => :user)
When I use the helper that way from a controller or a view it works nice but when trying to use it from a spec file it gives this error:
undefined local variable or method `rails_admin' for #RSpec::Core::ExampleGroup::Nested_2:0xbe04948>
I guess that I have to add something to my spec_helper.rb file in order to load rails_admin. But after googling for a while and looking to rails_admin gem's spec_helper, I cannot figure out what...
Any help will be apreciated!
I found it in spec_helper.rb of rails_admin.
Include the following code into spec_helper.rb.
RSpec.configure do |config|
...
config.include RailsAdmin::Engine.routes.url_helpers
end
I tested using debugger. It can be called
> new_path(:model_name => :user)
=> "/admin/user/new"
I added this line to individual specs that needed rails_admin urls and it allowed me to reference the methods mentioned in a prior post, but without interfering with my non-admin urls.
include RailsAdmin::Engine.routes.url_helpers
Example of method within spec
index_path(:model_name => :client)
I am using Rails 5.0, Rspec 3.5 and Capybara 2.10.1

Resources