什么是Ruby中类似于Python的getattr函数的等效实现?

11

我是Rails的新手,正在尝试进行一些重构(将列出标题的部分渲染器放在app/views/shared中)。该渲染器显示日期以及标题。但是,渲染器的不同用户使用不同的日期。在进行重构的过程中,我遇到了

title_date = list_titles.created_on

我希望给渲染器的另一个用户

title_date = list_titles.updated_on

那么我可以使用通过参数(使用 :locals 参数)传递的字符串吗?我知道在 Python 中我可以这样做:

date_wanted = 'created_on'
title_date = getattr(list_titles, date_wanted)

但我不知道如何在Ruby中实现这一点。(显然,在Rails中,我会从调用部分渲染器的视图中传递date_wanted字符串。)


参见:https://dev59.com/a0fRa4cB1Zd3GeqP70kf - dreftymac
4个回答

14

在 Ruby 中相应的语句:

date_wanted = :created_on
title_date = list_titles.send(date_wanted)

Rubocop建议:在使用send时,最好使用list_titles.__send__或者list_titles.public_send - Ramon Dias

4
我认为对于原问题的答案是发送:

irb(main):009:0> t = Time.new
=> Thu Jul 02 11:03:04 -0500 2009
irb(main):010:0> t.send('year')
=> 2009

send允许您在对象上动态调用任意命名的方法。


0
你可以像这样在模型中添加一个函数。
def get_date(date)
  return created_on if date == 'created'
  return updated_on
end

0
Matt的回答对于你的确切问题是正确的,而我可能完全误解了你的情况,但是...
我会通过本地哈希将整个用户对象传递到局部视图中。
render( 
  :partial => "shared/titles", 
  :object => @titles, 
  :locals => { :user => @user } 
)

然后在局部调用中使用一个辅助方法来返回每个标题的正确日期,类似于:

<p><%= title_date_for_user(title, user) %></p>

将用户和每个标题对象传递给辅助方法。
def title_date_for_user(title, user)
  case user.date_i_like_to_see
  when "created_on"
    title_date = title.created_on
  when "updated_on"
    title_date = title.updated_on
  end
  return title_date.to_s(:short)
end

date_i_like_to_see 方法位于 User 模型中,根据特定用户的某些逻辑返回一个字符串(created_onupdated_on)。

这种方法将大部分逻辑隐藏起来,使视图保持简洁。此外,它还可以轻松地添加针对特定用户的其他功能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接