在Rails 3.1控制器动作中急切加载,响应_json

时间:2011-10-23 23:46:33

标签: jqgrid ruby-on-rails-3.1

这是我到目前为止所拥有的:

class Show < ActiveRecord::Base
  belongs_to :event

  # use default_scope so shows are ordered by date by default
  default_scope order("date ASC")
end

class Event < ActiveRecord::Base
  has_many :shows, :dependent => :destroy
  has_and_belongs_to_many :users

  scope :future, lambda { includes(:shows).joins(:shows).where("shows.date > ?", Date.today).group("event_id") }

  def start_date
    shows.first.date
  end

  def end_date
    shows.last.date
  end

  def ends_in_future?
    end_date > Date.today
  end
end

我想创建一个与jqGrid一起使用的控制器动作。到目前为止,使用Event.includes(:shows).all.to_a返回JSON字符串中的所有节目,但我无法抓住start_dateend_date,这是有点可以理解的。是否可以在JSON中呈现派生/计算的属性?

我还注意到每个事件的节目都不在JSON字符串中。有没有什么方法可以获得所有事件,包括用JSON字符串呈现的子节目实体?

非常感谢, 达尼。

编辑:在控制器操作中使用as_json(:include => :shows)部分解决了这个问题。这将返回事件以及每个事件的所有关联节目。唯一剩下的就是弄明白我如何在json字符串中包含start_dateend_date ......

编辑:这是我原来的控制器操作代码 - 它可能不是最好的代码,因为我仍然在Rails周围感受:

matches = Event.includes(:shows).all
respond_to do |format|
   format.json {render :json => matches.as_json(:include => :shows)}
end

事实证明,我不必先运行查询 - 它只是响应json请求的一部分。我应该先仔细阅读as_json规范!这是我的控制器操作中的解决方案:

respond_to do |format|
      format.json {render :json => Event.all.as_json(:include => :shows, :methods => [:start_date, :end_date])}
end

渲染一切,包括“派生”方法。不幸的是,这似乎产生了很多疑问。这提供了我想要的json字符串,但它是最好的方法吗?很想听听任何改进的方法。

1 个答案:

答案 0 :(得分:1)

您可以将选中的列添加到事件记录中,如下所示:

Event.includes(:shows).joins(:shows).select("events.*, MIN(shows.date) as start_date, MAX(shows.date) as end_date").all

您可能需要使用其他名称(例如“show_start_date”,“show_end_date”)对这些列进行别名,因为事件记录已经包含您已定义的start_date和end_date方法。你将不得不解决方法名称冲突。