如何将activerecord关联作为字符串传递给方法?

时间:2014-06-20 14:30:09

标签: ruby-on-rails activerecord

鉴于以下关联:

用户has_many Ultimate_Source

用户has_many Budget_Source

如何创建以下方法:

def foo(source)
  user = User.find(1)
  user.source.id
end

这样

foo(ultimate_sources)

返回:

user.ultimate_sources.id

感谢。

3 个答案:

答案 0 :(得分:0)

如果source ==:ultimate_sources或source ==:budget_sources,则以下内容应该有效。

user.send(源).ID

如果source是一个字符串,您总是可以使用source.to_sym将其转换为符号。

send方法采用表示方法名称的符号,并将消息发送到该对象以执行该方法并返回该方法返回的内容。

http://ruby-doc.org/core-2.1.2/Object.html#method-i-send

答案 1 :(得分:0)

您可以使用方法.send

def foo(source)
  user = User.find(1)
  user.send(source.to_s).id
end

方法.try(如果source不是User的方法,则不会引发NoMethodError):

def foo(source)
  user = User.find(1)
  user.try(source.to_s).id
end

但我真的希望 source不是来自用户输入的内容。如果我将delete作为source变量的值发送,该怎么办?它会删除用户......

我强烈建议您限制可能的方法,在您的情况下,它可能是这样的:

def foo(source)
  user = User.find(1)
  user.try("#{source.gsub('_sources', '')}_sources").try(:id)
end

此代码版本可以保护您将destroy作为source值发送:

foo('ultimate_sources') # => user.ultimate_sources.id
foo('destroy') # => nil
foo('destroy_sources') # => nil
foo('budget') # => user.budget_sources.id

答案 2 :(得分:0)

你也可以加入一个保护条款以保证安全。

def foo(source)
   return if (source != 'ultimate_sources') || (source != 'budget_sources')

   user = User.find(1)
   user.send(source).id
end