Can I reduce duplication in the serialization of a ruby hash?
HTTParty, by default, converts the :query
hash into what it calls 'rails style query parameters':
For a query:
get '/', query: {selected_ids: [1,2,3]}The default query string looks like this:
/?selected_ids[]=1&selected_ids[]=2&selected_ids[]=3
Since you are doing a POST, it is possible/preferable to send your hash in the body of the request rather than in the query string.
def post_com(hsh)
self.class.post('some_url', body: hsh.to_json, headers: headers, format: :plain)
end
This has the advantage that it doesn't do any transformation of the payload and the query string length limit doesn't apply anyway.
For the record, you can disable the default 'rails style' encoding like this:
class Api
include HTTParty
disable_rails_query_string_format
...
end
You can also roll your own custom query string normalizer by passing a Proc
to query_string_normalizer
.
Rails return JSON serialized attribute with_indifferent_access
use the built-in serialize
method :
class Whatever < ActiveRecord::Base
serialize :params, HashWithIndifferentAccess
end
see ActiveRecord::Base docs on serialization for more info.
Rails as_json with conditions
I think you could try add some method like active_bars
which will return exactly what you need like:
def active_bars
bars.where active: true
end
or you could even add new relation:
has_many :active_bars, -> { where active: true }, class_name: '..', foreign_id: '..'
and then you will be able write:
@foo.as_json(
except: [:created_at, :updated_at],
include: {
active_bars: { only: [:ip_addr, :active] }
}
)
How to serialize/deserialize ruby hashes/structs with objects as keys to json
JSON only allows strings as object keys. For this reason to_s is called for all keys.
You'll have the following options to solve your issue:
The best option is changing the data structure so it can properly be serialized to JSON.
You'll have to handle the stringified key yourself. An Hash produces a perfectly valid Ruby syntax when converted to a string that can be converted using Kernel#eval like Andrey Deineko suggested in the comments.
result = json.transform_keys { |key| eval(key) }
# json.transform_keys(&method(:eval)) is the same as the above.The Hash#transform_keys method is relatively new (available since Ruby 2.5.0) and might currently not be in you development environment. You can replace this with a simple Enumerable#map if needed.
result = json.map { |k, v| [eval(k), v] }.to_h
Note: If the incoming JSON contains any user generated content I highly sugest you stay away from using eval since you might allow the user to execute code on your server.
Related Topics
How to Save Values into a Yaml File
Rebase Rails Migrations in a Long Running Project
Iconv Deprecation Warning with Ruby 1.9.3
Install Any Version of Ruby with Rvm on Mavericks
Maintaining Cookies Between Mechanize Requests
How to Specify Output File Encoding in Ruby
Passenger: Internal Server Error
When to Use a Lambda in Ruby on Rails
Is There a "Main" Method in Ruby Like in C
Handling Namespace Models (Classes) in Namespace
How to Switch to an Older Version of Rails
Active Admin - Refresh Second Drop Down Based on First Drop Down, Ruby on Rails
Ruby Dsl (Domain Specific Language) Repositories, Examples
What Is the "Equals Greater Than" Operator => in Ruby
Visit_Psych_Nodes_Alias: Unknown Alias: Default (Psych::Badalias)