2016-05-04 30 views
0

我想将下面的逻辑移到其他地方,以便我可以在我的控制器和rake任务中使用它。如何在rake任务中呈现json

我的控制器动作看起来是这样的:

def show 
    @user = User.find(params[:id]) 

    @account = # load account 
    @sales = # load sales 
    .. 

    render :json => { 
    "user": user, 
    "account": @account.map do |a| 
     JSON.parse(a.to_json(include: :addresses)) 
     end, 
     "sales": @sales.map do |s| 
     JSON.parse(s.to_json(include: :products)) 
     end 
    } 
end 

基本上一点是,我必须遍历关联,因此JSON有其中的所有数据。

我该如何将这个逻辑移到别的地方,然后我可以在我的控制器动作中调用它,也可以在rake任务中调用它。

+0

一个想法是;你创建一个'无表模型'(它是一个普通的Ruby类),开启一个API来完成这项工作。然后你可以从任何地方调用它 – illusionist

+0

你可以覆盖[as_json](http://apidock.com/rails/Hash/as_json)方法到用户模型中,然后从控制器以及从rake任务中调用它。 –

回答

1

将代码提取到presenter或使用ActiveModel::Serializers,以便控制器和Rake任务调用此新类。

class UserPresenter 
    def initialize(user, account, sales) 
    @user = user 
    @account = account 
    @sales = sales 
    end 

    def as_json(*) 
    { 
    "user": @user, 
    "account": @account.map do |a| 
     JSON.parse(a.to_json(include: :addresses)) 
     end, # or @account.as_json(include: :addresses)) 
    "sales": @sales.map do |s| 
     JSON.parse(s.to_json(include: :products)) 
     end # or @sales.as_json(include: :products)) 
    } 
    end 
end 

# In the controller 
render json: UserPresenter.new(@user, @account, @sales) 
+0

渲染方法不是在幕后做一些工作吗?不知道我可以重构它。 – Blankman

+0

我不确定。我通过传递一个Hash来获得成功,并将其转换为JSON。 –