Фильтрация (поиск) модель с несколькими параметрами в хэш


Эта функция в моем профиле модель получит хэш-поиска и фильтрации в таблице в зависимости от этих значений. Я думаю, что есть что-то вроде шаблона для такой стандарт поведения, сейчас я закончил с этим (к сожалению, мне пришлось приводить здесь код, поэтому он не может работать по каким-то причинам, но вы получите идею).

Просто к сведению: мы будем хранить в модели некоторые строки, содержащие несколько данных, каждое из этих полей должно быть один-ко-многим (нарушение нормальности дБ). Я приведу пример: country_preferences является строкой пополняется в формате HTML выберите :несколько => правда. В строке я тогда найти такие ценности, как: ["Австралия", "Китай", "Великобритания"].

  def search opts # This default doesn't work the way I would like = {:user_type => :family}

    #TODO: default opts value in method sign if possible
    opts[:user_type] ||= :family

    # initial criteria
    fields= "user_type= ?"
    values= [opts[:user_type]]

    # each field filters the list in one of these three ways
    staight_fields = [ :country, :first_name, :last_name, :nationality ]
    like_fields = [:country_preferences, :keyword, :languages ]
    bool_fields = [:driver, :housework, :children ]

    # cicle the options and build the query    
    opts.each do |k, v|
      if straight_fields.include? k
        fields += " AND #{k} = ?"
        values += v
      elsif like_fields.include? k
        fields += " AND #{k} like %?%"
        values += v
      elsif bool_fields.include? k
        fields += " AND #{k} = ?"
        values += v == 'true'
      else
        logger.warn "opts #{k} with value #{v} ignored from search"
      end
    end

    # execute the query and return the result
    self.registered.actives.where([fields] + values)   
  end

Я думаю, что я могу использовать больше объем , но как я могу объединить их вместе? В общем, как я могу сделать этот код намного лучше?

Босс, представляя проект, сказал один-ко-многим отношения для такого поля будет боль в спине. Что вы думаете об этом прагматичное решение?



20941
8
задан 1 февраля 2011 в 12:02 Источник Поделиться
Комментарии
1 ответ

Вы смотрели в заранее существующую gem для этого? Я нашел один называется has_scope , что, кажется, это может делать именно то, что вы пытаетесь исправить. Вы должны добавить объем для каждого из фильтров, а затем добавить некоторые has_scope звонки в ваш контроллер.

Вот несколько примеров. Я не так хорошо знаком с Rails 3 диапазоны, как я с 2, поэтому, скорее всего, код не будет работать как есть.

Модель:

class Profile < ActiveRecord::Base
scope :country, lambda {|country| where(:country => country) }
scope :keyword, lambda {|keyword| where(["keyword LIKE :term", {:term => "%#{keyword}%"}]) }
scope :driver, where{:driver => true)
end

Контроллер:

class ProfileController < ApplicationController
has_scope :country
has_scope :keyword
has_scope :driver, :type => :boolean
end

6
ответ дан 1 февраля 2011 в 01:02 Источник Поделиться