当我需要连接2个表时,如何在Rails中将对象的索引呈现为JSON?

时间:2015-07-27 21:02:33

标签: ruby-on-rails ruby json model

标题很难解释我的需要。

这就是需要的......

我有两个型号。 Walkthru和Walkthru完成。

Walkthru有列(:id,:name,:reward) WalkthruComplete具有列(:id,:user_id,:walkthru_id)

如果用户在我的应用程序中完成了一个walkthru / guide,则会向WalkthruComplete写一个新行,例如说user_id 17已完成walkthru_id 2.他们可能会获得一些积分。

现在,我需要获取所有可用的walkthrus。这很简单。但是,我想要包含的不仅仅是Walkthru。(:id,:name,:reward)。我还想包括一个我在飞行中组成的专栏“完成”。在我的Walkthru #index中,我将检查请求Walkthru #index的特定用户是否有任何WalkthruComplete行。如果他们这样做,那么对于那些特定的walkthrus,'completed'将被设置为YES。如果他们不这样做,'completed'将被设置为NO。

user_id未设置为Walkthru的原因是因为某些walkthrus允许任何用户,包括未登录的用户。其他人仅用于登录用户,并奖励那些签到用户的人。

最后我想要一些像......

{
    "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 个答案:

答案 0 :(得分:1)

基本上,您希望为JSON响应提供表示层。我将对你所拥有的代码做一些假设,并概述我将采取哪些措施来解决这个问题。

给出模型中的辅助方法

class Walkthru < ActiveRecord::Base
  has_many :walkthru_completions

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

你模特的装饰师:

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

然后在您的控制器中,假设您有@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

此结构允许您与模型分开定义JSON。