首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >检查上次保存的忽略Object.new的项

检查上次保存的忽略Object.new的项
EN

Stack Overflow用户
提问于 2018-05-26 13:13:39
回答 1查看 29关注 0票数 0

我有一个标准的Rails视图,它在new.html.erb页面的日期条件上显示警告框。

代码语言:javascript
运行
复制
<% if @user.items.last.issue_date + 2.years > Date.today %>
  ...show warning...
<% end %>

但是,这会阻塞,因为最后一条记录与用户关联表单控制器中创建的空对象。

代码语言:javascript
运行
复制
def new
  @user = User.find(params[:user_id])
  @item = @user.items.new
end

看来我可以通过做

代码语言:javascript
运行
复制
<% if @user.items.offset(0).last.issue_date + 2.years > Date.today %>

但这似乎根本行不通,因为Postgres的医生说

偏移量0与省略偏移子句相同。

所以,我有两个问题:

  • 是否有更好的方法来检查仅保存在数据库中的记录?
  • 为什么ActiveRecord偏移调用行为(显然)与Postgres文档所称的不同?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-26 13:49:38

您在控制器中创建的新@item位于@user.items集合中,但尚未保存到数据库中。

这就是为什么添加.offset(0)是为您工作的,因为就像一个.where()子句一样,您正在将返回的记录的条件更改为仅从数据库返回的记录,而您的新记录不是其中之一。

过滤掉它的另一种方法可能是这样:

代码语言:javascript
运行
复制
@user.items.reject(&:new_record?).last

或者这个:

代码语言:javascript
运行
复制
@user.items.reject { |item| item == @item }.last

但是,与从数据库中提取大量或多个记录相比,.reject的性能要差一些。

否则,您所拥有的就会起作用,但是我会使用一个不那么脆弱的(补偿可能会改变)和更多的意图--显示如下的查询:

代码语言:javascript
运行
复制
@user.items.
  where('issue_date < ?', 2.years.ago).
  order(issue_date: :desc).
  limit(1).
  last

理想情况下,您可以将其封装在模型中的User查询方法或作用域中,该模型名为@user.issues.expired@user.issued_less_than(2.years.ago),或任何对应用程序有用的内容。

另外,我希望@user.items是在关系上排序的,因为Postgres并不总是以任何特定的顺序返回项,除非您指定了一个。

代码语言:javascript
运行
复制
has_many :items, -> { order(id: :desc) }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50543156

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档