如果条件为真,则将值包含在数组中

Include value in array if condition is true

仅当条件为真时才在数组中包含值的惯用 Ruby 方法是什么?

class ItemPolicy
    def initialize(user)
        @user = user
        @allowed = user.manager?
    end

    # Suggest improvements to the permitted_attributes method
    def permitted_attributes
        [:name, :details] + (@allowed ? [:price] : [])
    end
end

这感觉不太Ruby-ish。

像这样:

def permitted_attributes
  Array[
    :name,
    :details,
    *@allowed ? :price : nil
  ]
end

如果您愿意,也可以在一行中:

def permitted_attributes
  [:name, :details, *@allowed ? :price : nil]
end

没什么问题,但我觉得该方法可能会随着时间的推移而增长并变得更加混乱。我不确定为什么 @allowed 在方法之外,但忽略了我可能会这样做:

def permitted_attributes
  permitted = [:name, :details]
  permitted += :price if @allowed
  permitted
end

这样你就可以随着时间的推移增加它并添加其他逻辑,同时保持它的可读性。

好吧,你可以这样做...

@allowed = false
def permitted_attributes
  [
    :name,
    :details,
    *(:price if @allowed),
  ]
end

老实说,我认为这有点令人困惑。真正最好的方法可能就是保持简单:

def permitted_attributes
  attrs = [:name, :details]
  attrs << :price if @allowed
  attrs
end
class Array
  def add_object_if(object_to_add)
    if yield
      self << object_to_add
    else
      self
    end
  end
end

arr = [1,2]
bool = true
arr.add_object_if(3) { bool }
p arr #=> [1, 2, 3]
bool = false
arr.add_object_if(4) { bool }
p arr #=> [1, 2, 3]

我唯一能想到的就是将条件包装到它自己的一个小方法中,这样可以更清楚地说明原因。

还想我会添加一个 attr_reader 来删除实例变量的重用。

class ItemPolicy
  attr_reader :allowed

  def initialize(user)
      @user = user
      @allowed = user.manager?
  end

  # Suggest improvements to the permitted_attributes method
  def permitted_attributes
    [:name, :details] + conditional_attributes
  end

  def conditional_attributes
    return [] unless allowed
    [:price]
  end
end