sql - Rails - has_one 与 WHERE 和 ORDER 的关系?

标签 sql ruby-on-rails ruby relationship has-one

我在用户模型中有以下关系。

has_many :subscriptions, dependent: :destroy
has_one :subscription, -> { where 'end_date >= ?', Date.today }

:订阅本质上是他们最新的月度订阅。 :subscriptions 是他们之前所有每月订阅(包括最新的)的数组。他们列出了 start_date、end_date、user_id、plan_id、payment_method。

当订阅计划升级或降级时,我将当前订阅的结束日期更改为 Date.today(表示订阅今天结束),然后创建一个从今天开始到一个月后结束的新订阅。

将 end_date 设为 Date.today 的问题在于 WHERE 子句将选取已取消的订阅和新的订阅。但是会支持取消的订阅,因为 SQL 查询在 ORDER BY 类上生成了主 ID 升序的标记。

ORDER BY "subscriptions"."id" ASC LIMIT 1

我这辈子都想不出如何将 ID 上的 ORDER BY 从 ASC 反转为 DESC。但我更喜欢它根据 created_at 时间戳进行排序。以下是仅用于排序的适当代码,但除了 ORDER BY 子句之外,我还需要 WHERE 子句。

has_one :subscription, -> { order 'created_at desc' }

有没有人想出如何将两者结合起来?

最佳答案

从 Rails 4 开始,当您调用 first 方法时,Rails 会自动添加按 id 排序。 (您可以调用 take 来避免这种情况。)所以我猜测 has_one 正在内部调用 first

既然 has_one 只是自动创建一个名为 subscription 的方法,为什么不自己创建呢?:

def subscription
  subscriptions.where('end_date >= ?', Date.today).order("created_at DESC").take
end

如果你不喜欢这个,从你的问题中不清楚你是否已经尝试过这个:

has_one :subscription, -> { where('end_date >= ?', Date.today).order("created_at DESC") }

您没有理由不能像这样将这两个项目链接起来。但我记得 Rails 4 first 将覆盖您的 order 指令并将其替换为 order(:id),因此这可能行不通。你可以通过说 @user.subscription.to_sql 来确定。

关于sql - Rails - has_one 与 WHERE 和 ORDER 的关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21344725/

相关文章:

java - 比较 SQL 中的元素(房间预订 WebApp)Java

sql - 是否可以告诉 SSMS 不检查 t-sql 脚本中是否存在列?

PHP - mySQL 如果行中有两个值则选择重复项并删除一个

mysql - 如何在单独的 mysql 表中搜索术语?

ruby-on-rails - “remember me” 复选框的集成测试失败

ruby-on-rails - 非法嵌套 : nesting within plain text is illegal

ruby - 智能生成组合的组合

ruby-on-rails - Ruby on Rails : Fixtures without Database

ruby-on-rails - 链轮在Rails 5上需要Ruby版本> = 2.5.0

ruby - Sinatra 和计算 View 名称