Rails Draper 的装饰器导致 ArgumentError
Posted
技术标签:
【中文标题】Rails Draper 的装饰器导致 ArgumentError【英文标题】:Rails Draper's Decorator caused ArgumentError 【发布时间】:2022-01-17 12:35:44 【问题描述】:我为 Rails 项目设置了 Draper 的装饰器来替换原来的助手。我将帮助代码移到了装饰器:
def birthday(date)
"MinYear#date.year - 1911 Month#date.month Day#date.day"
end
并在 View 中添加 .decorate
文本以使用它
<%= user.decorate.birthday %>
但是,这会导致ArgumentError wrong number of arguments (given 0, expected 1)
def birthday(date)
如果我删除第一个日期,它将显示NoMethodError undefined method 'date' for #<UserDecorator:0x000055570cbafc58>
"MinYear#date.year - 1911 Month#date.month Day#date.day"
如何解决这些错误?
【问题讨论】:
date
是在哪里定义的?这是 User 模型上的一个属性?
用户模型def age Date.today.year - birthday.year end
上定义的日期
【参考方案1】:
引发ArgumentError
是因为您调用birthday
而不传入date
。
执行<%= user.decorate.birthday(Date.current) %>
将使错误消失。
但是,这可能不是您想要的,因为 date
是在 User
模型中定义的。
装饰东西最简单的方法是使用delegate_all。它将使来自 User
模型的所有方法在装饰器中可用。
class UserDecorator < Draper::Decorator
delegate_all
def birthday
"MinYear#date.year - 1911 Month#date.month Day#date.day"
end
end
请注意,装饰器中声明的任何方法都将覆盖模型中声明的方法,在您的情况下为birthday
。例如,如果装饰器中有其他调用birthday
的方法,它将使用装饰器中的方法,而不是模型中的方法,通过调用model.birthday
可以使用。
另一种方法是调用model 对象上的方法:
class UserDecorator < Draper::Decorator
def date
model.date
end
def birthday
"MinYear#date.year - 1911 Month#date.month Day#date.day"
end
end
【讨论】:
非常感谢我使用decorates_association :user
而不是 delegate_all
,这是一个好习惯吗?谢谢
你为什么会有decorates_association :user
,这对我来说毫无意义。定义了birthday
的装饰器看起来如何?对于User
模型,通常应该存在UserDecorator
。 decorates_association :user
表示您在 User
模型内有一个名为 user
的关联。
我确实在用UserDecorator,发现两种写法都有效
我主要使用delegate_all
。我不认为有好的或坏的做法,但可能有人会说,如果一个模型有大量的方法并且使用了delegate_all
,它将使所有方法都可用,即使它们中的大多数都没有使用。
有时间请看一下,***.com/help/someone-answers。谢谢。以上是关于Rails Draper 的装饰器导致 ArgumentError的主要内容,如果未能解决你的问题,请参考以下文章
rspec 使用 draper Decorator 测试视图