Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql Rails:保存属性上的筛选条件并检查条件是否通过?_Sql_Ruby On Rails_Ruby_Ruby On Rails 4_Filter - Fatal编程技术网

Sql Rails:保存属性上的筛选条件并检查条件是否通过?

Sql Rails:保存属性上的筛选条件并检查条件是否通过?,sql,ruby-on-rails,ruby,ruby-on-rails-4,filter,Sql,Ruby On Rails,Ruby,Ruby On Rails 4,Filter,我有一个SaaS应用程序,其中一个帐户有许多用户 在帐户中,帐户所有者可以对申请成为帐户一部分的用户指定某些筛选器。例如,他可以设置必须满足这些要求条件才能接受用户:user.age>21,user.name.count>4 我正在考虑创建一个FilterCondition模型,它属于Account,其中一行可以看起来像Account\u id:1,属性:“年龄”,条件字符串:“>21”或Account\u id:1,属性:“电话类型”,条件字符串:==iphone” 然后,当我只想接受满足这些

我有一个SaaS应用程序,其中一个帐户有许多用户

在帐户中,帐户所有者可以对申请成为帐户一部分的用户指定某些筛选器。例如,他可以设置必须满足这些要求条件才能接受用户:user.age>21,user.name.count>4

我正在考虑创建一个FilterCondition模型,它属于Account,其中一行可以看起来像
Account\u id:1,属性:“年龄”,条件字符串:“>21”
Account\u id:1,属性:“电话类型”,条件字符串:==iphone”

然后,当我只想接受满足这些条件的用户时,请执行以下操作

  #User.rb
  def passes_requirements?
    account.filter_conditions.each do |filter_conditions|
      attr = filter_condition.attribute
      return false if self.attr != filter_condition.condition
    end 
    true
  end
我知道这是完全错误的语法,但它应该让我明白我想做什么


允许帐户保存需求条件,然后检查用户是否满足这些要求的任何建议方法?

如果将条件字符串分为一个比较器(例如
)和要比较的值,会更容易:

class FilterCondition < ActiveRecord::Base
  belongs_to :account

  validates :attribute, presence: true
  validates :comparator, presence: true
  validates :value, presence: true

  def matching_users(query_chain = User.where(account: account))
    query_chain.where("#{attribute} #{safe_comparator} ?", value)
  end

  private
  def safe_comparator
    safe_values = ['=', '>', '>=', '<', '<='] # etc
    return comparator if safe_values.include? comparator
    ''
  end
end

如果我们也要比较字符串,这会起作用吗?就像“用户电话类型必须是iPhone或Android”,只要
FilterCondition
value
的DB type是字符串,它就会过滤掉使用其他电话的用户。生成的ActiveRecord查询将是
where(“phone\u type=?,'iPhone')
。执行OR查询(例如Android或iPhone)比较困难,需要重构
FilterCondition
(但并非不可能)查询链。它仍然是字符串类型。我们有没有办法做#{safe_comparator.to_comparator}之类的事情?它应该是一个字符串。实际上,您发送的是一个Arel/ActiveRecord查询字符串以及一组值。然后以sql安全的方式将问号替换为值,并将整个字符串转换为sql查询。这就是我们最终提出的解决方案:
class Account < ActiveRecord::Base
  #....
  has_many :filter_conditions
  def filtered_users
    query = User.where(account: self)
    filter_conditions.each do |filter_condition|
      query = filter_condition.matching_users(query)
    end
    query
  end

end


account = Account.first

filter_1 = FilterCondition.create(
  account: account,
  attribute: :age,
  comparator: '>=',
  value: 21
)
filter_2 = FilterCondition.create(
  account: account,
  attribute: :age,
  comparator: '<=',
  value: 99
)


account.filtered_users