新手问题 请教如何去掉 query 里的检索条件

miserytan · 2017年06月05日 · 最后由 miserytan 回复于 2017年06月07日 · 1755 次阅读

controller 里 new 方法 我使用 query 帮我增加一些检索条件来检索用户,现有关系是

class Poll< ApplicationRecord
  has_many :clients, :dependent => :destroy
  belongs_to :user
end
class Client < ApplicationRecord
  belongs_to :user
  belongs_to :poll
end
class User< ApplicationRecord
  has_many :clients
  has_many :polls
end

如下是 Client 控制器,用于查询用户是否在当前的 Client 表里,“在”的话,查询出“不在”的并显示出来,“不在”的话,查询出“在”的并显示出来 Client 表里没数据也就是最开始在 client 表里创建 user 的时候,:flag 标签是“f”也就是查询出“不在”client 表里的 user

def new
    retrieve_clients_add_query
    sort_init(@query.sort_criteria.empty? ? [['lastname', 'asc'], ['firstname', 'asc']] : @query.sort_criteria)
    sort_update(@query.sortable_columns)
    @query.sort_criteria = sort_criteria.to_a
    if @query.valid?
      case params[:format]
      when 'csv', 'pdf', 'xls', 'vcf'
        @limit = Setting.issues_export_limit.to_i
      when 'atom'
        @limit = Setting.feeds_limit.to_i
      when 'xml', 'json'
        @offset, @limit = api_offset_and_limit
      else
        @limit = per_page_option
      end
      @users_count = @query.object_count(:flag => 'f')
      if Redmine::VERSION.to_s > '2.5'
        @users_pages = Paginator.new(@users_count,  @limit, params[:page])
        @offset = @users_pages.offset
      else
        @peoples_pages = Paginator.new(self, @users_count,  @limit, params[:page])
        @offset = @users_pages.current.offset
      end
      @users_count_by_group = @query.object_count_by_group
      @user = @query.results_scope(
        :include => [:projects],
        :search => params[:search],
        :order => sort_clause,
        :limit  =>  @limit,
        :offset =>  @offset,
        :type => 'User',
        :flag => 'f'
      )

      @filter_tags = @query.filters["tags"] && @query.filters["tags"][:values]
      @groups = Group.all.sort
      @departments = Department.order(:name)

    end
  end

现在问题是 我需要通过在别的方法里将 query 里的这个 options[:flag] 给去掉 我的写法如下:

if @poll.status_id == 3
  @clients= Client.where("client_id =?", @poll.id)
  @clients.delete_all  
end

这样是把所有的数据都清掉了,options[:flag] 标签还在,每次在 client 控制器里 new 的时候都会去判断 options[:flag] 的值时“f”或者“t”,根据值的不同进行不同的 select 查询语句,但是我希望的是能将 options[:flag] 这个标签去掉,因为每次 new 动作执行完,:flag 标签都自动变化成相反的了,比如一开始是 f,等我选完了,标签变成 t,要求是不能在@query.results_scope这里去掉 flag 这个参数。

有大神给个良策吗,在这个地方纠结半天了

良策,自己顶.....

已经解决了,虽然没人问津,但是通过其他很多帖子找到了一丝灵感,并验证好用。感谢这么多人看我的帖子

params 理论上跟一个 Hash 差不多,如果你想删除某个 key,params.delete :flag 就可以了,返回值是 :flag 的值。

这里如果你的查询很复杂,建议你实现一个简单的 QueryModel 类来实现,类似于

class QueryModel
  attr_accessor :flag, :keyword

  def initialize(params = {})
    params.each do |k, v|
       send :"#{k}=", v
    end
  end

  def to_query
    query = Model.all
    if flag
      query = query.where()
    end
    query
  end
end

不用写太好看,但是结构就干净好多了

另外,真假值转换用 ActiveModel::Type.lookup(:boolean).cast(value),包括数字之类的类型,都有对应的转换类

jasl 回复

哇 感谢大神,我昨天 就想着用键值对的方式先查询出来,然后 转换真假值,不过最后我的解决方式比较丑陋,现在看来 我可以改一下了,感谢

需要 登录 后方可回复, 如果你还没有账号请 注册新账号