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



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

<% if @user.items.last.issue_date + 2.years > Date.today %>
...show warning...
<% end %>

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

def new
@user = User.find(params[:user_id])
@item = @user.items.new
end

看来我可以通过做

<% if @user.items.offset(0).last.issue_date + 2.years > Date.today %>

但这似乎根本不应该起作用,因为 Postgres 文档说

OFFSET0 与省略 OFFSET 子句相同。

所以,我有两个问题:

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

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

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

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

@user.items.reject(&:new_record?).last

或者这个:

@user.items.reject { |item| item == @item }.last

但是,与从数据库中提取大量或记录相比,.reject的性能会低。

否则,您拥有的工作有效,但我将使用不那么脆弱(偏移量可能会更改(和更具意图揭示的查询,如下所示:

@user.items.
where('issue_date < ?', 2.years.ago).
order(issue_date: :desc).
limit(1).
last

理想情况下,你可以将其包装在模型中名为@user.issues.expired@user.issued_less_than(2.years.ago)User查询方法或范围中,或任何适用于你的应用的内容。

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

has_many :items, -> { order(id: :desc) }

相关内容

  • 没有找到相关文章

最新更新