Ruby convert Object to Hash
class Gift
def initialize
@name = "book"
@price = 15.95
end
end
gift = Gift.new
hash = {}
gift.instance_variables.each {|var| hash[var.to_s.delete("@")] = gift.instance_variable_get(var) }
p hash # => {"name"=>"book", "price"=>15.95}
Alternatively with each_with_object
:
gift = Gift.new
hash = gift.instance_variables.each_with_object({}) { |var, hash| hash[var.to_s.delete("@")] = gift.instance_variable_get(var) }
p hash # => {"name"=>"book", "price"=>15.95}
Converting an object to a hash of values in Ruby
Assuming all data you want to be included in the hash is stored in instance variables:
class Foo
attr_writer :a, :b, :c
def to_hash
Hash[*instance_variables.map { |v|
[v.to_sym, instance_variable_get(v)]
}.flatten]
end
end
foo = Foo.new
foo.a = 1
foo.b = "Test"
foo.c = Time.now
foo.to_hash
=> {:b=>"Test", :a=>1, :c=>Fri Jul 09 14:51:47 0200 2010}
Rails Object to hash
If you are looking for only attributes, then you can get them by:
@post.attributes
Note that this calls ActiveModel::AttributeSet.to_hash
every time you invoke it, so if you need to access the hash multiple times you should cache it in a local variable:
attribs = @post.attributes
Converting an object to a hash in Ruby
If you can't update GameTeam
to add a to_h
method, then you can get the needed instance variables and make your own:
class GameTeam
def initialize(game_id, hoa, result, team_id)
@game_id = game_id
@hoa = hoa
@result = result
@team_id = team_id
end
end
obj = GameTeam.new('2012030154', 'home', 'LOSS', '30')
%i[game_id hoa result team_id].map { |ivar| [ivar, obj.instance_variable_get("@#{ivar}")] }.to_h
# {:game_id=>"2012030154", :hoa=>"home", :result=>"LOSS", :team_id=>"30"}
Convert Active Record Object into Hash
You can get it from below query,
Hash[Person.all.collect { |user| [user.email, user.attributes.except(:email).values] }]
If you want to omit other attributes like created_at
& updated_at
, run
Hash[Person.all.collect { |user| [user.email, user.attributes.except(:email, :created_at, :updated_at).values] }]
How do I convert a String object into a Hash object?
The string created by calling Hash#inspect
can be turned back into a hash by calling eval
on it. However, this requires the same to be true of all of the objects in the hash.
If I start with the hash {:a => Object.new}
, then its string representation is "{:a=>#<Object:0x7f66b65cf4d0>}"
, and I can't use eval
to turn it back into a hash because #<Object:0x7f66b65cf4d0>
isn't valid Ruby syntax.
However, if all that's in the hash is strings, symbols, numbers, and arrays, it should work, because those have string representations that are valid Ruby syntax.
Convert Array of objects to Hash with a field as the key
users_by_id = User.all.map { |user| [user.id, user] }.to_h
If you are using Rails, ActiveSupport provides Enumerable#index_by:
users_by_id = User.all.index_by(&:id)
Convert an Object to hash then save it to user's column
HStore
I remembered there's a PGSQL datatype called hStore
:
This module implements the hstore data type for storing sets of
key/value pairs within a singlePostgreSQL
value. This can be useful
in various scenarios, such as rows with many attributes that are
rarely examined, or semi-structured data. Keys and values are simply
text strings.
Heroku supports it and I've seen it used on another live application I was observing.
It won't store your object in the same way as Stripe
's data
attribute (for that, you'll just need to use text
and save the object itself), but you can store a series of key:value
pairs (JSON).
I've never used it before, but I'd imagine you can send a JSON object to the column, and it will allow you to to use the attributes you need. There's a good tutorial here, and Rails documentation here:
# app/models/profile.rb
class Profile < ActiveRecord::Base
end
Profile.create(settings: { "color" => "blue", "resolution" => "800x600" })
profile = Profile.first
profile.settings # => {"color"=>"blue", "resolution"=>"800x600"}
profile.settings = {"color" => "yellow", "resolution" => "1280x1024"}
profile.save!
--
This means you should be able to just pass JSON objects to your hstore
column:
#app/controllers/profiles_controller.rb
class ProfilesController < ApplicationController
def update
@profile = current_user.profile
@profile.update profile_params
end
private
def profile_params
params.require(:profile).permit(:x, :y, :z) #-> z = {"color": "blue", "weight": "heavy"}
end
end
As per your comments, it seems to me that you're trying to store "interest" in a User
from another model.
My first interpretation was that you wanted to store a hash of information in your @user.interests
column. Maybe you'd have {name: "interest", type: "sport"}
or something.
From your comments, it seems like you're wanting to store associated objects/data in this column. If this is the case, the way you're doing it should be to use an ActiveRecord association.
If you don't know what this is, it's essentially a way to connect two or more models together through foreign keys in your DB. The way you set it up will determine what you can store & how...
#app/models/user.rb
class User < ActiveRecord::Base
has_and_belongs_to_many :interests,
class_name: "Support",
join_table: :users_supports,
foreign_key: :user_id,
association_foreign_key: :support_id
end
#app/models/support.rb
class Support < ActiveRecord::Base
has_and_belongs_to_many :users,
class_name: "Support",
join_table: :users_supports,
foreign_key: :support_id,
association_foreign_key: :user_id
end
#join table = users_supports (user_id, support_id)
by using this, you can populate the .interests
or .users
methods respectively:
#config/routes.rb
resources :supports do
post :interest #-> url.com/supports/:support_id/interest
end
#app/controllers/supports_controller.rb
class SupportsController < ApplicationController
def interest
@support = Support.find params[:support_id] # I need the post's id they are on
current_user.interests << @support
end
end
This will allow you to call @user.interests
and bring back a collection of Support
objects.
Okay, look.
What I suggested was an alternative to using interest
column.
You seem to want to store a series of hashes for an associated model. This is exactly what many-to-many
relationships are for.
The reason your data is being populated twice is because you're invoking it twice (u=
is creating a record directly on the join model, and then you're inserting more data with <<
).
I must add that in both instances, the correct behaviour is occurring; the join model is being populated, allowing you to call the associated objects.
What you're going for is something like this:
def interest_already_sent
support = Support.find params[:id]
current_user.interests << support
end
When using the method I recommended, get rid of the interest
column.
You can call .interests
through your join table.
When using the code above, it's telling Rails to insert the support
object (IE support_id
into the current_user
(IE user_id
) interests
association (populated with the UserInterestSelf
table).
This will basically then add a new record to this table with the user_id
of current_user
and the support_id
of support
.
how to covert array object to hash in rails
hash.each {|k,v| hash[k] = v.map{|e| {id: e[:id], name: e[:name]}}}
and if you can use select_all
method get the array of hash, not array of object, so you doesn't need to covert object to hash.
ModelName.connection.select_all("select id, name from <table_name>;")
=> [{id:xxx, name: xxx}.......]
convert hash to object
You need to add recursivity:
class Hashit
def initialize(hash)
hash.each do |k,v|
self.instance_variable_set("@#{k}", v.is_a?(Hash) ? Hashit.new(v) : v)
self.class.send(:define_method, k, proc{self.instance_variable_get("@#{k}")})
self.class.send(:define_method, "#{k}=", proc{|v| self.instance_variable_set("@#{k}", v)})
end
end
end
h = Hashit.new({a: '123r', b: {c: 'sdvs'}})
# => #<Hashit:0x007fa6029f4f70 @a="123r", @b=#<Hashit:0x007fa6029f4d18 @c="sdvs">>
Related Topics
Ruby - Send Get Request with Headers
Error: Failed to Build Gem Native Extension (Ruby Extconf.Rb): MAC Osx
Getting Uninitialized Constant Error When Trying to Run Tests
What Is the Ruby Equivalent of Python's Getattr
Trouble Yielding Inside a Block/Lambda
Editing Existing Rails Migrations Is a Good Idea
Error Installing Ruby with Rvm (Osx 10.8)
Rails: Unable to Access Log File
How to Send Message Using Gmail API with Ruby Google API Client
Faulty Ruby Compilation with Rvm: Getting 'Undefined Symbol: Rb_Digest_Md5_Init' While Running Racku
Ruby on Rails Send_File Doesn't Work Until I Refresh the Page
How to Escape #{ from String Interpolation
What Is the Use of Secret_Key_Base in Rails 4