rails-settings: NoMethodError: undefined method `merge' for []:Array Rails-settings:NoMethodError:[]:Array没有定义“merge”方法

3
我将尝试将rails-settings gem(https://github.com/100hz/rails-settings)实现到使用Ruby 1.8.7的Rails 3项目中。
设置和检索设置功能完美,但是如果我尝试获取特定用户的所有设置,则会出现错误。
因此,在“rails控制台”中,以下内容有效:
user = User.find(123)
user.settings.color = :red
user.settings.color

但是,如果我尝试获取所有设置:
user.settings.all

我得到了以下错误信息:

NoMethodError: undefined method `merge' for []:Array

发生在 /[...]/.rvm/gems/ruby-1.8.7-p334/bundler/gems/rails-settings-883114dfd933/lib/rails-settings/settings.rb 的第55行:`all'

来自(irb):5

其中,settings.rb的第55行代码如下:
#retrieve all settings as a hash (optionally starting with a given namespace)
def self.all(starting_with=nil)
  options = starting_with ? { :conditions => "var LIKE '#{starting_with}%'"} : {}
  vars = thing_scoped.find(:all, {:select => 'var, value'}.merge(options))

  result = {}
  vars.each do |record|
    result[record.var] = record.value
  end
  # line 55 is below this one...
  @@defaults.select{ |k| k =~ /^#{starting_with}/ }.merge(result).with_indifferent_access
end

这里有什么问题?还是这是1.8.7和1.9.2之间的差异?

请问你能否添加@@defaults的初始化代码?这将有助于识别问题。看起来你那里有一个数组而不是哈希表。 - Roberto Decurnex
你可以在这里找到整个文件:https://github.com/100hz/rails-settings/blob/master/lib/rails-settings/settings.rb - Harry Smeerlap
2个回答

3

这是关于Ruby 1.8.7和1.9.2的区别。

在Ruby 1.8.7中,Hash的select方法会返回一个由数组组成的数组。

例如:

{:a => 'a', :b => 'b', :c => 'c'}.select {|k, v| v > 'a'} #=> [[:b,'b'],[:c,'c']]

当使用Ruby 1.9.2运行相同的内容时,将返回:

{:a => 'a', :b => 'b', :c => 'c'}.select {|k, v| v > 'a'} #=> {:b => 'b',:c => 'c'}

您需要对结果进行后处理,将其转换回哈希值,或者使用类似于inject的东西。

编辑:

这是inject的一个快速/丑陋的示例。

{:a => 'a', :b => 'b', :c => 'c'}.inject({}) {|r, e| e[1] > 'a' ? r.merge({e[0] => e[1]}) : r }

从语义学的角度来说:

collection.inject(container) { |container, element| select_condition ? container + element : container }

编辑2:(基于@CaleyWoods的帖子)
Hash[*@@defaults.select{ |k,v| k =~ /^#{starting_with}/ }.flatten].merge(result)
|k, v|将防止不必要的警告。

这篇文章展示了使用 * 和 flatten 创建哈希表的例子,同时也说明了这一点。 - Caley Woods
@Caley_Woods 这是一篇很棒的帖子!我会“借鉴” * + flatten 技巧。 - Roberto Decurnex
@Harry 我会在 Github 上联系维护者,让他们知道你必须使用 RUBY_VERSION < 1.9 的解决方法。看起来你正在使用 RVM,我可能会将 RVM 切换到 1.9.2 并查看 NeX 的示例是否仍然适用于 1.9.2。如果是的话,我会考虑提交一个 pull request,因为新代码可以与多个 Ruby 版本一起使用。 - Caley Woods

0

这似乎是在尝试对一个不是 Ruby 数组类中的方法的数组进行合并。合并支持哈希,看起来你返回的对象不是正确的类型。作者肯定依赖于哈希,在倒数第二行调用了 'with_indifferent_access',试图允许你使用字符串或符号从哈希中选择项目。

我现在无法进一步检查这个 gem,我希望我能提供更有帮助的答案。如果这个问题没有得到解决,我会回来帮助你。

不确定为什么作者在选项和变量中使用双引号和单引号。他还试图手动填充哈希而不是使用 inject。这并不可怕,但我认为你从文件中发布的少量代码有改进的空间。


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