将Rails变量传递给case语句

时间:2014-04-24 05:45:39

标签: ruby-on-rails ruby arrays

我使用Rails并拥有一个我希望控制输出的数组。

简而言之,如果@projects中存在具有ID的项目,那么我不想输出数组的相应部分(如果存在)。因此,如果存在ID为1的项目,那么我不想输出@array[1],即使它已存在。

以下硬编码案例陈述成功运作,以避免输出@array[1]@array[2]@array[3]

@array.each do |key, value|
  case key when '1','2','3' then
    next # Skip this array key
  end
  # Otherwise, do something else
end

但是我实际上希望通过ActiveRecord动态传递这些代码而不是硬编码'1','2','3'。我试着建立一个字符串:

@projects_string = @projects.map {|element|
  "'#{element.id}'"
}.join(',')

这成功输出'1','2','3'。但我无法找到将其传递到案例陈述中的方法。这无法匹配:

@array.each do |key, value|
  case key when "#{@projects_string}" then
    next # Skip this array key
  end
  # Otherwise, do something else
end

有没有办法使用这种方法实现这一点,或者使用一些Rails'更好的方法来实现这一点。能力?

我确实浏览了this answer,这似乎最相关,但无法看到如何实现它。

4 个答案:

答案 0 :(得分:1)

你也可以这样做。

@project_arr = @projects.map{|p| p.id.to_s}

@array.each do |key, value|
  unless @project_arr.include?(key.to_s)
    #YOUR CODE GOES HERE
  else
    # SKIP IT
  end
end

答案 1 :(得分:1)

您不应该使用字符串,而是使用数组并执行

@array = Array.new
@array = @projects.map{|arr| arr.id}

@array.each do |key, value|
  if @array.include?(key)
    #code to skip if project is included
  else
    #your code
  end
end

数组可以比字符串

更容易用于比较

答案 2 :(得分:1)

我觉得这取决于您正在处理的集合类型:Array或ActiveRelation。

如果它们只是数组,并且您希望@array的元素不在@parent中,那么您可以这样做:

@array - @parent

如果它们都是ActiveRecord对象,为什么不在创建它时过滤掉@array

@array = Project.where.not(id: @projects.pluck(:id))

对于正在迭代的集合中的每个元素,必须扫描查找数组(@projects)似乎效率低下(n ^ 2)。

答案 3 :(得分:0)

您可以尝试以下操作:

@array = [1,2,3,4]
@projects = [2,3]
@array.each do |key|
  case
  when true === @projects.include?(key)
    next
  end
  puts "Doing something else for #{key}"
end

输出:

Doing something else for 1
Doing something else for 4