Ruby on Rails + Active_Record:如何在结果中包含子计数?

4

我通过在文件夹模型中创建一个as_json方法,解决了如何将子元素包含在to_json结果中的问题。

def as_json(options={ })
  super(
          options.merge(
                  :include => {
                          :children => { }
                  }
          )
  )
end

上面的代码给了我一个子元素列表,但我想要的是包括计数而不是子元素列表。我还想将其过滤为仅包括“Active”子元素。
我似乎无法找到一种有效的方法来实现这一点。
我正在使用下面的代码返回文件夹列表。
def index
  @folders = Folder.all(:order => "Name")

  respond_with(@folders) do |format|
    format.jsonp { render :json => @folders, :callback => params[:callback] }
  end
end

最后,我希望确认计数器在所有结果中都能够返回,而不仅仅是JSON。虽然JSON最重要,但我确实希望它也能出现在其他结果中。

我以为我可以通过使用.size将计数器添加到@folders查询后返回的每个文件夹中。然而,这似乎行不通...

接下来,我开始研究向Folder模型添加一个方法,例如...

def child_count
  write_attribute(:child_count, children.size)
end

但是在看了一下之后,我意识到这样做并不会起作用...

所以现在我正在研究 :select 来进行一些 SQL 魔法... 但如果有更简洁的方法,我真的不想走这条路。

欢迎提供建议!


好的,我找到了答案,但是由于我的声望不到100,我无法回答自己的问题。因此,这里是我博客上答案的链接... - Altonymous
1个回答

4

只需添加一个child_count方法来返回子元素数量,然后在as_json中使用:methods选项:

def as_json(options = { })
    super(options.merge(:methods => :child_count))
end

如果options中已经有:methods,那么你在使用merge时需要更加小心。以下代码可能比直接合并更好:

def add_child_count(options)
    options[:methods] = [ options[:methods], :child_count ].flatten.compact.uniq
    options
end

def as_json(options = { })
    super(add_child_count(options))
end

对于XML,你需要使用to_xml而不是as_json来执行几乎相同的操作。

我刚刚想到了这个。我试图回答自己的问题,但我的声望太低了,它不让我这么做。不过还是谢谢你,那正是我发现的! - Altonymous
哦,有一个问题...那只是将它添加到JSON中。我以为我可以创建一个as_xml方法来将其添加到XML中,但这不起作用。然而,我发现我可以使用to_xml来实现需要相同功能的操作。 - Altonymous
@Altonymous:XML 应该也是同样的处理方式。我还为 merge 处理添加了一个“偏执狂”更新,以防将来有人说 x.as_json(:methods => :aha!) - mu is too short

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接