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
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">>
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}
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 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 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
.
Related Topics
Ruby Templates: How to Pass Variables into Inlined Erb
How to Convert Json to a Ruby Hash
How to Check a Checkbox in Capybara
Uniq by Object Attribute in Ruby
How to Group by Count in Array Without Using Loop
Using Layouts in Haml Files Independently of Rails
Extract Number from String in Ruby
Rails 4.0 Strong Parameters Nested Attributes With a Key That Points to a Hash
Why Isn't Self Always Needed in Ruby/Rails/Activerecord
Fibonacci Sequence in Ruby (Recursion)
Match a String Against Multiple Patterns
403 Forbidden on Rails App W/ Nginx, Passenger
Rails Devise: User_Signed_In? Not Working
In Ruby Why Won't 'Foo = True Unless Defined(Foo)' Make the Assignment
Nokogiri Will Not Install - Error: Failed to Build Gem Native Extension
How to Split a String to Get All the Substrings by Ruby
Invalid Active Developer Path on MAC Os X After Installing Ruby