ruby-on-railspaper-trail-gem

Display all versions of individual records in Papertrail


I'm building a league system and currently it stores and updates the players 'elo score' depending on the result. Now, I'm trying to add in 'HighCharts' to display the players elo score over the season in a sweet looking line chart. Someone suggested I use Papertrail to store the updates and I have got that all installed.

Now here comes my problem, I can't seem to figure out how to spit out the users elo_score versions in an array easy for 'HighCharts' to use. I can get the last updates to elo_score:

Last updated score = <%= @player.versions.last.reify.elo_score %> 

But I can't seem to find the syntax to spit out all the 'versions' for 'elo_score'. Something like "1000, 1020, 1043, 1020".

I've also tried:

<%= @player.versions.map { |version| version.reify.elo_score} %>

But this gives me "undefined method `elo_score' for nil:NilClass". While just <%= @player.versions.map { |version| version.reify %> spits out all information in the record and obviously not just the elo_score.

Can anyone help? Sorry if I've not made this clear, I'm absolute brand new to rails, and this is just a fun project in my spare time but I'm having a blast!

Thanks alot!


Solution

  • What you did here:

    @player.versions.map { |version| version.reify.elo_score }
    

    Is perfectly fine to take all those scores and put them in an array. The problem that you're getting (the nil:NilClass stuff) is coming because at least one reify is nil. That is, that some version doesn't have a reify.

    If each version is supposed to have a reify, be sure to add that as a model validation, and find in your code where the reify is being set and see why it's nil.

    If it's okay for a version to have a nil reify, you could accomplish it a number of ways, but the straightforward and explicit way would look like this:

    elo_scores = []
    @player.versions.each do |version|
        unless version.reify.nil?
            elo_scores << version.reify.elo_score
        end
    end
    

    I would suggest putting this in to a method, like get_elo_scores, and then you could more easily call it like:

    @player.get_elo_scores
    

    EDIT For clarification from the comments:

    Your User model (or Player model, whatever you named it) should have a method that looks like this:

    def get_elo_scores
        elo_scores = []
        self.versions.each do |version|
            unless version.reify.nil?
                elo_scores << version.reify.elo_score
            end
        end
        return elo_scores
    end
    

    I apologize for not making this clearer, but you won't have access to @player within this method because that only exists in the context of your controller and view. The above is now a proper instance method: it will call .versions upon itself, and the rest is fine. I also added an explicit return call at the end.

    Now you will be able to call @player.get_elo_scores on any User (or Player) object.

    Hope that helps!