twoixter / trackoid

Trackoid is an easy scalable analytics tracker using MongoDB and Mongoid
MIT License
88 stars 16 forks source link

Trackoid breaking to_json? #12

Closed nickw closed 12 years ago

nickw commented 13 years ago

I'm getting a NoMethodError when trying to call to_json on a Mongoid model with tracking:

tracking.rb#62:

define_method("#{name}_data") do
  raise NoMethodError
end

I've been able to get around it by overriding to_json in my model and removing any *_data attributes from the json hash.

twoixter commented 12 years ago

Mmmhh... Sorry to comment so late. I've been busy lately and I haven't done much with Trackoid.

I see. The line you pointed out is the one that "hides" the Mongoid internal hash field. Seems to me your solution is the correct answer, overriding "as_json" in the model so that you remove those *_data attributes.

Try to override "as_jason" instead of "to_json" since it's more correct since a long time. (http://stackoverflow.com/questions/2572284/override-to-json-in-rails-2-3-5)

mattiassvedhem commented 12 years ago

I'm having the same issue, can't get it to work, overriding as_json in the model but I still occasionally get a NoMethodError.

Any thoughts on work arounds ? =)

nickw commented 12 years ago

Hmm, what does your #as_json method look like? Here's mine:

def as_json(options = nil)
  super(except: [:views_data, :downloads_data, :likes])
end
twoixter commented 12 years ago

The most possible cause for the no_method error is a name conflict for a field. Check that the model doesn't have any field named like the :tracked one.

Anyway, @nickw posted the best workaround until I can double-check this and fix it, using the except: option inside the #as_json method.

twoixter commented 12 years ago

In fact, this is what it's supposed to work: you WILL want to :except the tracked fields somehow, because if you add them I think you'll progressively get more and more data, potentially throwing Kb's and Kb's thru the JSON (as those fields gets growing and growing and...) :-)

The most sensible thing to do, I think is to manually include the data you're supposed to export in the JSON payload. Provably along the lines of:

def as_json(options = nil)
    super(except: [:blah, :blah, :blah]).tap do |attrs|
        # Manually add customized data for JSON, not the whole field!
        attrs[:views] = views.today
    end
end

I'm typing this as I go -- it's not tested, but I think you see what I mean. ;-)

nickw commented 12 years ago

I agree that the raw tracking data doesn't belong in the #as_json hash, but I also don't think that Trackoid should break #as_json "out of the box". Perhaps there's a way to hide the tracking data from #as_json by default?

twoixter commented 12 years ago

But it should not break when using JSON. At least with my current Ruby and RoR versions (ruby 1.9.2p0, RoR 3.1.0).

I just added a new commit adding an additional spec to check that. (I haven't updated the gem version, since this commit only adds a new spec, no new functionality or fixes.).

Yep, I know I may be a bit outdated with that Rails! :-) So, please check to see if this new spec passes on your system!

mattiassvedhem commented 12 years ago

Cool, I got it working! thanks a lot.