Audited audited_changes confusion - ruby-on-rails

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.

Related

ActiveAdmin Changing Links to Name Instead of ID

For one of my models in ActiveAdmin, it is changing the URLs to use the name instead of ID.
For example: http://localhost:3000/admin/product/PH instead of http://localhost:3000/admin/product/1
I don't understand why it's doing that since all of the other models are working correctly (using ID).
This model has no models/product.rb file.
# app/admin/product.rb
ActiveAdmin.register Product do
permit_params :name,
:amount,
:description
end
I checked the documentation and didn't see anything that looks like it would make this happen.
Also, all of the other SO posts I've seen related to name and URL seem to be trying to do the opposite - changing the default route to use name (instead of ID).
Late reply, but I just met the same problem.
It was due to slug. I just remove slug from my model and it worked.
Hope it could help someone.

ActiveRecord serialize not working properly with Hash column

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?

Regenerate keys in Mongoid?

Just trying out Mongoid at the moment, I've run into an issue that's probably pretty simple but has me at a loss:
I have a really simple Article model:
class Article
include Mongoid::Document
field :title, :type => String
field :content, :type => String
key :title
referenced_in :subject
validates_presence_of :title
end
I added key :title after I had already created one test record. Newly created records work as expected, but the first Article (which originally had the normal mongoid object id) behaves strangely:
In rails views this first article still returns its object id instead of the new key. ie using link_to article.name, article returns:
Show
... when all the rest return the parameterized keys, like:
Show
If I click that link I get "Record not found". I tried loading and resaving this record in the console, and after that calling article.id on that record did return the parameterized key, but it still shows up the old way in the view and doesn't work.
So, a couple questions:
What's going on here?
How do you fix it?
This situation indicates to me that if you set a field on a mongoid model to be the key, you need to be really sure that it will never change. How do you handle something like using the title of an article as a slug, then, when those may occasionally need change?
Thanks!
Well, since _id is immutable, your only option is to reinsert this document with your new 'sluggish' id and delete the old one.
And yes, _id format and shard key (if you use sharding) are the two things you better have right from the beginning :-)
Everything else can be fixed relatively easily.

Is there a way for mongoid to use integer(number) as a default id rather than long hash value?

I just want to have default characteristic of ActiveRecord which uses incremental integers as id to reduce the length of the url.
For example, first article created will have url like "app.com/articles/1" which is default in ActiveRecord.
Is there any gem that supports this in mongoid?
You could always generate shorter, unique tokens to identify each of your records (as an alternative to slugging), since your goal is just to reduce the length of the URL.
I've recently (today) written a gem - mongoid_token which should take any of the hard work out of creating unique tokens for your mongoid documents. It won't generate them sequentially, but it should help you with your problem (i hope!).
You can try something like this:
class Article
include Mongoid::Document
identity :type => Integer
before_create :assign_id
def to_param
id.to_s
end
private
def assign_id
self.id = Sequence.generate_id(:article)
end
end
class Sequence
include Mongoid::Document
field :object
field :last_id, type => Integer
def self.generate_id(object)
#seq=where(:object => object).first || create(:object => object)
#seq.inc(:last_id,1)
end
end
I didn't try such approach exactly (using it with internal ids), but I'm pretty sure it should work. Look at my application here:
https://github.com/daekrist/Mongologue
I added "visible" id called pid to my post and comment models. Also I'm using text id for Tag model.
AFAIK it's not possible by design:
http://groups.google.com/group/mongoid/browse_thread/thread/b4edab1801ac75be
So the approach taken by the community is to use slugs:
https://github.com/crowdint/slugoid

Rails - serialize another activerecord model

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!

Resources