ruby-on-rails - 如何将 joins 方法与 first_or_initialize 一起使用而不是 find_or_initialize_by (Rails)?

标签 ruby-on-rails ruby join inner-join

有没有办法重写下面的流程,目前使用find_or_initialize_by,使用joins方法?

对于上下文 - 我有 users(员工)在系统中记录他们的 attendances(user 有很多 attendances考勤记录属于用户)。

Attendance.find_or_initialize_by(
  user: User.find_by(name: 'Bob'),
  date: Time.zone.today
)
.update(...) # Update some columns after this

我正在尝试使用 .joins 重写它,如下所示:

Attendance.joins(:user)
  .where(users: {name: 'Bob'}, date: Time.zone.today)
  .first_or_initialize
  .update(...) # Update some columns after this

我的测试结果喜忧参半:

  • 只需要更新记录的测试用例通过
  • attendance 记录尚不存在的测试案例(即我必须initialize 的案例)失败

错误信息是 ActiveRecord::RecordInvalid:验证失败:用户必须存在。 但我很困惑,因为用户确实存在 - 如果我使用 byebug 进行调试,用户就在那里。

最佳答案

与其从出勤模型开始,我更倾向于从用户开始,像这样:

User.find_by(name: 'Bob').attendances.find_or_initialize_by(date: Time.zone.today).update(...)

这使事情易于阅读。您可以添加一个关联扩展方法来使事情更方便:

class User < ActiveRecord::Base
  has_many :attendances do
    def for_date(date)
      find_or_initialize_by(date: Time.zone.today)
    end
  end
end

# Then call with:
User.attendances.for_date(Time.zone.today)

根据您对该出勤记录所做的操作,您还可以让您的 for_date 方法接受额外的参数。

first_or_initialize 已根据以下内容删除:https://api.rubyonrails.org/classes/ActiveRecord/Relation.html . 感谢@engineersmnky 的更正。该方法未记录,但看起来像是一个错误。

关于ruby-on-rails - 如何将 joins 方法与 first_or_initialize 一起使用而不是 find_or_initialize_by (Rails)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56217535/

相关文章:

ruby-on-rails - Rails 回形针和亚马逊 S3 'PermanentRedirect'

ruby - 如何阻止来自 Ruby Mechanize Gem 的访问?

sql - Access 2010 : How to make a query result updateable?

ruby-on-rails - 具有连接和顺序的不同记录

ruby-on-rails - 将 SSL 配置从我的计算机切换到托管服务器

ruby-on-rails - FactoryGirl未定义方法 `create='

ruby-on-rails - 期望 <"index"> 但使用 <[]> 渲染

ruby-on-rails - 连接被拒绝 - 连接(2)用于 "localhost"端口 25 rails

ruby - 需要一个支持 ruby​​ 的副本集和 eventmachine 的 mongo 驱动程序

SQL 内部连接在外部连接内;嵌套改变结果