在Rails 4中显示相应text_field_tag值的优雅方式

时间:2014-08-30 13:21:38

标签: ruby-on-rails ruby ruby-on-rails-4

所以我的问题是以一种简单明了的方式展示一个模型。

那么目前的工作原理是什么?

在我的观众中,这很好用:

<%= text_field_tag(:first_name, (current_user.present? ? current_user : '').first_name.present? ? current_user.first_name : '') %> 

然而,这太长并且很难维持,特别是当我还有几个字段时。

所以为了避免我在我的控制器中做到这一点

def user_vals(value)
    if(current_user.present?)
      current_user.value.present? ? current_user.value : ''
    end
    return ''
  end

在此控制器中,我可以调用user_vals(:first_name),但会得到undefined method值&#39;`错误。此外,我不能只是打电话

<%= text_field_tag(:first_name, @user_vals(:first_name)) %>

由于括号中出现了一些语法错误,但这不是真正的问题。

所以我的最终目标是拥有这样的东西:

<%= text_field_tag(:first_name, @user_vals(:first_name)) %>

而不是我上面给出的第一个代码。我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:1)

在这种情况下,您可以使用try。只需写下:

<%= text_field_tag(:first_name, current_user.try(:first_name)) %>

请参阅:http://apidock.com/rails/Object/try

答案 1 :(得分:0)

我建议退后一步,尝试使用Duck Typing来解决这个问题......

您现在拥有的是current_user方法。如果用户未登录,此方法可以返回它想要的任何对象,并且该对象可以响应它想要的任何内容。这是一个简单的例子:

def current_user
  @user || OpenStruct.new(first_name: "")
end

注意:我假设@user拥有当前已登录的用户...但这可能是对super的调用,或其他任何操作,具体取决于您的实施。

所以现在,不是根据current_user方法返回的对象的类型进行分支,而是现在可以不加考虑地使用返回的对象。

current_user.first_name # => Either the User object's first name or `""`

你可以通过创建例如一个GuestUser类并返回GuestUser.new而不是上面的OpenStruct。 Guestuser将是一个非数据库支持的模型,可以根据需要响应任意数量的方法。

这个想法也被许多其他人所代表。并且使用类来防止基于nil的重复代码切换实际上有一个名称:特殊情况模式。作为一个快速免费的示例,请参阅Guest User RailsCast。或者,如果您订阅Ruby Tapas,请务必查看第112: Special Case集。 Avdi Grimm的优秀书籍Confident Ruby也深入讨论了这个主题以及其他许多主题,我强烈推荐这一主题。