我有一个模型Avatar
,它有一些属性,包括original_url
,large_url
和thumb_url
。我使用transloadit进行文件上传,这就是我存储这些图像的原因。
我还有一个方法,它接受一些参数,其中一个是字符串。我不是为每个不同的头像大小创建多个方法,而是创建一个具有要使用的属性的参数(即:original_url
,large_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>
如何获取此字符串并将其转换为对象的属性。
答案 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