I'm trying to store a Hash in a table column, using ActiveRecord's serialize method but I can't make it work. I'm using Rails 4.2.0 and RailsApi 0.3.1
This is my model:
class Agreement < ActiveRecord::Base
serialize :phone_numbers, Hash
end
phone_numbers is a text column like it's required.
Then in the console:
a = Agreement.new(phone_numbers: {"dario" => "12345"})
a.phone_numbers
=> "{\"dario\"=>\"12345\"}" #(Note this is a string, not a Hash as I would expect)
a.phone_numbers["dario"]
=> "dario" #(Not "12345" as I would expect)
Am I missing soemthing?? Thank you!
The behavior you're showing is consistent with the serialize call being wrong, either misnamed column, or missing entirely. Eg. https://gist.github.com/smathy/2f4536d3e59b7a52c855
You're showing the right code in your question, so either you didn't copy-paste that correctly, or perhaps it you haven't restarted your rails console since adding/correcting that serialize call?
Related
I am upgrading a Rails 3 project to Rails 4 and it is breaking on one of my models that uses an ActiveRecord Store property. My model looks like the following:
class ModelClass < ActiveRecord::Base
attr_accessible :attr_1, ..., attr_n, as: :admin
store :properties, accessors: [:attr_1, ..., :attr_n], coder: JSON
end
The :properties field is a text field in Postgres.
And when I try to access the data in this model I get the following JSON::ParserError:
795: unexpected token at '{"attr_1"=>"", ..., "attr_n"=>""}'
These records were all created in Rails 3, and before upgrading to Rails 4 my model class did not have coder: JSON at the end of the store call. It looks like the data in the database is not being serialized correctly does anyone have any idea why and how to fix it? Is it because my data looks like a ruby hash with the => hash rocket in the database?
Yes, the JSON parser fails because the string isn't a json.
You could fix your records by evaluating the string and converting it to json afterwards. eval is to be used carefully but if this is a one time job then you could probably run something like this in the rails console.
ModelClass.all.each do |m|
m.properties = eval(m.properties).to_json
m.save
end
Not tested, please try on one record before updating your entire table.
I'm user of Ruby on Rails.
I made active model like this.
class User < ActiveRecord::Base
attr_protected :id
serialize :user_info, Hash
serialize :user_auth, Array
serialize :user_addr
end
I want to get the column names which contains a serialized object and type.
I'm looking forward to the method like this.
ex )
User.serialized_columns #=> {:user_info => Hash, :user_auth => Array, :user_addr => nil}
Would you help me?
Yes, you can get it using the method serialized_attributes which returns a Hash where key is the column name and value is the class of the column
So, you can get the serialized columns as
User.serialized_attributes
But you have modify the value of each key according to your requirement.
Im using collectiveidea's audited solution for auditing in rails.
So, there's a column (audited_changes) that is a TEXT definition in the database. When i retrieve an audit from the database, i get a plain string, and when i call that attribute in the view is non formated string. In the rdocs it says that theres a serialized hash of all changes. How can i get this hash? Also, in the same docs it says that there's access to old_attributes and new_attributes, how is this?
In my view:
<%= #audit.action %> # => update
<%= #audit.audited_changes %> # => --- name: - oldname - newname code: - oldcode - newcode
Or any chance on formatting this?
I think there might currently be a bug in audited. Are you using 3.0.0rc1? That is what I am using and I had something similar happen. First off, it didn't seem to recognize "Audit" as an ActiveRecord object, so I created an empty model in app/models/audit.rb. Once I did that I was seeing the behaviour you are seeing. To fix it, I removed the app/models/audit.rb and added an config/initializers/audited.rb with this in it:
include Audited::Adapters::ActiveRecord
This is an old question but I have an alternative answer that seems to be working well for me using Rails 4.2. Instead of using the initializer in the above answer I suggest keeping the model and adding "serialize :audited_changes" to the top.
class Audit < ActiveRecord::Base
belongs_to :user
serialize :audited_changes
end
You could use the built-in Audited::Audit model to query its data.
For example,
audit = Audited::Audit.last
audit.audited_changes # => {"name"=>["Steve", "Ryan"]}
"Steve" is the old value, "Ryan" is the new value. By default, the hash is stored in yaml format in the database.
I may be using serialized objects wrong, so I apologize in advance. For an activity feed, I'm using a serialized meta-data column to simplify the database call. E.g. for the activity feed, I'm just pulling in Activity objects with the appropriate user_id. I'm adding in the line_item object as seen here:
class Activity < ActiveRecord::Base
serialize :data
activity = Activity.new(:user_id => user_id...)
if activity.source_type == "LineItem"
line_item = LineItem.find(activity.source_id)
activity.update_attributes(:data => line_item)
end
Then I call it via some partials where "book" is the meta-data bit:
= link_to image_tag(item.data.book.image_url),
book_path(item.data.book.id)
This works fine on my box, but Heroku gives me "TypeError (can't dump anonymous class Class)". What gives?
I think you need to explicitly say what type you are serializing to. So the syntax would be:
serialize :data, Hash
I'm looking to serialize an incomplete/temporary model as an attribute of another model such as:
class User < ActiveRecord::Base
serialize :pending_post
end
Where pending_post is assigned an activerecord model:
...
user.pending_post = Post.new(:title => "Whatever", :message => "whatever")
user.save
But instead of saving the yaml for the new Post model, the pending_post attribute is nil (in the DB and on reload). The serialize works great with other objects, Hashes, Arrays, etc, but comes up nil in this case. This is Rails 2.3.9, but I did a quick test with 3.0.1 and saw the same results. I found this description of the issue from years ago: http://www.ruby-forum.com/topic/101858.
I know I could manually serialize/deserialize the object (which works fine) or serialize just the post.attributes, but I'm curious if anyone knows why this acts as it does? It seems if the new post is saved before being assigned to user.pending_post, then just the ID is saved as the user.pending_post attribute. I'm pretty sure it's intentional and not a bug, but I quite don't understand the reasoning. Is it poor form to serialize an active_record model?
I think you need to serialize/save the attributes, not the post object itself, like so:
user.pending_post = {:title => 'Whatever', :message => 'whatever'}
user.save
Then later you can turn it into a real post:
user.posts.create user.pending_post
And I'd probably take it a step further (as I so often do) with a user method:
def save_post
self.posts.create self.pending_post
end
I hope this helps!