【问题标题】:Returning a virtual attribute in a select query在选择查询中返回虚拟属性
【发布时间】:2014-03-06 16:04:23
【问题描述】:

我正在构建的应用程序的一部分是 API。最近的更改意味着我需要将两个不同版本的数据放入我的 json 提要中。我认为最好的方法是在数据库中进行必要的更改,然后创建一个虚拟属性来连接数据。

在我的模型中,我有 event_summary 虚拟属性,使用 <%= @event.event_summary => 在视图中输出没有问题:

def event_summary
    "#{title} (#{start_datetime.strftime('%A %d %b, %l:%M%P')})"
end

在我的 API 控制器中,我有一个选择查询,用于获取 API 响应所需的属性(此处为简化版):

respond_to :json

def index
  respond_with Event.select('title, event_summary')
end

问题是它总是返回一个未定义的列错误:

PG::UndefinedColumn: ERROR: column "event_summary" does not exist LINE 1: SELECT title, event_summary FROM "events"

我也尝试了以下方法,但得到了相同的结果:

respond_with Event.select('title', :event_summary)

如果这有什么不同的话,我正在使用 Postgres。

有没有办法做到这一点?

谢谢!

【问题讨论】:

    标签: ruby-on-rails postgresql activerecord ruby-on-rails-4


    【解决方案1】:

    您不能在 select 方法中使用虚拟属性,因为它将被转换为 SQL 语句,并且该字段在您的表中不存在。但是,您可以在 SQL 中进行连接和日期格式化:

    Event.select('title, (title || ' ' || to_char(start_datetime, 'HH12:MI:SS')) as event_summary')
    

    这实际上将创建一个“虚拟属性”,但在 sql 领域中,它将返回具有该属性的事件,并由 to_char postgres 方法格式化。日期格式不完全是您所拥有的,因此您需要根据您的需要对其进行调整(通过更改格式字符串 'HH12:MI:SS'),详见此处的文档:http://www.postgresql.org/docs/8.2/static/functions-formatting.html

    希望对您有所帮助。

    【讨论】:

    • 这正是我寻求的答案
    【解决方案2】:

    我认为这可能会满足您的需求:

    def index
      render :json => Event.all.to_json :methods => :event_summary
    end
    

    [编辑]

    IIRC respond_with 不适用于 to_json,所以你必须使用 render

    【讨论】:

    • 这正是我想要的。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-18
    • 1970-01-01
    相关资源
    最近更新 更多