将字符串转换为models属性

时间:2014-07-20 00:19:07

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

我有一个模型Avatar,它有一些属性,包括original_urllarge_urlthumb_url。我使用transloadit进行文件上传,这就是我存储这些图像的原因。

我还有一个方法,它接受一些参数,其中一个是字符串。我不是为每个不同的头像大小创建多个方法,而是创建一个具有要使用的属性的参数(即:original_urllarge_url等)。

def avatar_for(user, img_size, img_url)
   url = user.avatar ? user.avatar.img_url : (Identicon.data_url_for user.username, img_size, [238, 238, 238])
  image_tag(......)
end

以上img_url,我将传递给我想要使用的特定属性,如下所示:

= avatar_for(current_user, 250, 'original_url')

然而,这会返回错误

undefined method `img_url' for #<Avatar:0x007fdc98217948>

如何获取此字符串并将其转换为对象的属性。

1 个答案:

答案 0 :(得分:2)

您正在研究Ruby消息系统的强大功能

ruby​​中的每个对象都可以使用send方法接收消息。例如'hello'.upcase输出为'HELLO'。使用send方法,您可以为同一输出编写'hello'.send(:upcase)。请注意,我使用了一个符号来表示要调用的方法的名称。

什么是优势?在我的示例中,:upcase可以来自变量(这就是您想要做的事情),但send也允许在其他对象上调用私有方法。

在您的情况下,使用的正确代码如下:

def avatar_for(user, img_size, img_url)
   url = user.avatar ? user.avatar.send(img_url) : (Identicon.data_url_for user.username, img_size, [238, 238, 238])
  image_tag(......)
end

然后你会像这样打电话给你的方法:

= avatar_for(current_user, 250, :original_url) # Using symbol instead of string

替代回答

在Rails中,所有模型(即从ActiveRecord::Base派生的对象)都将该属性存储在类似数组的存储中。例如,如果您的User模型具有name属性,则可以使用user[:name]

访问该模型

因此,如果您需要替代send方法,,假设user.avatar是活动记录模型,则可以编写以下内容:

def avatar_for(user, img_size, img_url)
   url = user.avatar ? user.avatar[img_url] : (Identicon.data_url_for user.username, img_size, [238, 238, 238])
  image_tag(......)
end