【问题标题】:Rails ActiveRecord get value from column, or from association's default if nilRails ActiveRecord 从列中获取值,如果为 nil,则从关联的默认值获取
【发布时间】:2021-10-16 01:17:03
【问题描述】:

我确定这已得到解答,但我的搜索失败了。

我有两个模型:

class Person < ApplicationRecord
    belongs_to :family
    # has column "last_name"
end

class Family < ApplicationRecord
    has_many :people
    # has column "last_name"
end

我想Person.take.last_name 到:

  • 如果 Person 的 last_name 不为零,则返回该值
  • 如果此人有家庭,请返回该家庭的last_name
  • 否则,返回 nil。

我可以做类似的事情

class Person < ApplicationRecord
    belongs_to :family
    # has column "last_name"

    def last_name_lookup
        last_name || family&.last_name || nil
    end
end

但想知道是否有内置的 rails 方法可以做到这一点,或者是否认为掩盖列的真实值是不合适的。

【问题讨论】:

  • 我可能会采用您的 last_name_lookup 方法(或装饰器、视图模型、助手等中的等效方法)。覆盖 last_name 本身可能会导致 last_name 列在您不期望的情况下更改为姓氏。
  • 您可以在创建时用Family#last_name 填充列Person#last_name 吗?如果是这样,您可以避免在运行时运行它并使用家庭关联执行 N+1 查询。如果您遍历人员并忘记在您的获取查询中包含家庭,这将导致 N+1 查询。尝试解决创建问题并规范您的基础
  • @muistooshort 谢谢,很有趣。您能否详细说明覆盖如何导致列在未预料到的情况下发生更改?
  • 如果您覆盖 Person#last_name,然后将 Person 放入编辑表单中并且该 Person 没有 last_name,则表单将以 last_name 中的姓氏结尾场地。然后表单返回服务器,并带有家庭的姓氏,此人最终得到last_name
  • 谢谢——很高兴知道

标签: ruby-on-rails ruby activerecord


【解决方案1】:

我不知道 Rails 的内置方式。但是你可以做

# in person.rb

def last_name # yes, overrides the built-in getter
  read_attribute(:last_name) || family&.last_name # will be nil if both last_names are nil
end

【讨论】:

    猜你喜欢
    • 2013-07-17
    • 1970-01-01
    • 1970-01-01
    • 2020-07-01
    • 1970-01-01
    • 2023-03-03
    • 2017-12-05
    • 2018-03-06
    • 1970-01-01
    相关资源
    最近更新 更多