1

The title is likely bad at explaining what I need.

Here's what that need is...

I have two models. Walkthru and WalkthruComplete.

Walkthru has columns (:id, :name, :reward) WalkthruComplete has columns (:id, :user_id, :walkthru_id)

If a user completes a walkthru/guide in my application, a new row will be written to WalkthruComplete, saying for instance that user_id 17 completed walkthru_id 2. They may be rewarded some points for this.

Now, I need to fetch all the available walkthrus. This is easy. However, I want to include more than Walkthru.(:id, :name, :reward). I also would like to include a column I make up on the fly called 'completed'. In my Walkthru#index, I will check to see if the particular user requesting the Walkthru#index has any WalkthruComplete rows. If they do, 'completed' would be set to YES for those particular walkthrus. If they don't, 'completed' would be set to NO.

The reason the user_id is not set to Walkthru is because some walkthrus are allows for any users, including non-signed in users. Others are only for signed in users, and reward points to those signed in users.

In the end I want something like...

{
    "walkthrus": [
        {
            "id": 1,
            "name": "Intro",
            "reward": 0,
            "completed": 0
        },
        {
            "id": 2,
            "name": "Widgets",
            "reward": 10,
            "completed": 1
        },
        {
            "id": 3,
            "name": "Gadgets",
            "reward": 10,
            "completed": 0
        }
    ]
}

1 Answer 1

1

Basically you want to have a presentation layer for your JSON response. I'll make some assumptions about the code you have and outline what I would do to solve this.

Given a helper method in your model

class Walkthru < ActiveRecord::Base
  has_many :walkthru_completions

  def completed_status(user)
    walkthru_completions.where(user_id: user.id).present? ? 1 : 0
  end
end

And a decorator for your model:

class WalkthruDecorator 
  def initialize(user, walkthru)
    @walkthru = walkthru
    @user = user
  end

  def as_json(*args)
    @walkthru.as_json(args).merge(completed: @walkthru.completed_status(@user))
  end
end

Then in your controller, let's assume you have a @user representing the current user:

class WalkthruController < ActionController
  def index        
    decorated_walkthrus = []

    Walkthru.all.each do |walkthru|
      decorated_walkthrus << WalkthruDecorator.new(@user, walkthru)
    end

    render json: decorated_walkthrus
  end
end

This structure lets you define your JSON separately from your model.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.