2016-09-01 2 views
0

Gegeben sei das folgende Beispiel als Basis ... und bitte korrigiere mich, wenn das nicht korrekt eingestellt ist.Wie führe ich eine Sonnenfleckensuche für ein bestimmtes Feld in einer has-many durch:

Migration Files:

class CreateUsers < ActiveRecord::Migration 
    def change 
    create_table :users do |t| 
     t.string :first_name, null: false 
     t.string :last_name, null: false 
     t.string :email, null: false 

     t.timestamps null: false 
    end 
    end 
end 

User.create(first_name:'John', last_name:'Smith', email:'[email protected]') # id: 1 
User.create(first_name:'Jane', last_name:'Smith', email:'[email protected]') # id: 2 

class CreateCustomAttributes < ActiveRecord::Migration 
    def change 
    create_table :custom_attributes do |t| 
     t.string :name, null: false 
     t.text :description, null: true 

     t.timestamps null: false 
    end 
    end 
end 

CustomAttribute.create(name:'is_married', description:'') # id: 1 
CustomAttribute.create(name:'has_children', description:'') # id: 2 
CustomAttribute.create(name:'number_of_children', description:'') # id: 3 

class CreateUserCustomAttributes < ActiveRecord::Migration 
    def change 
    create_table :user_custom_attributes do |t| 
     t.references :user, null: false 
     t.references :custom_attribute, null: false 
     t.text  :value, null: true 

     t.timestamps null: false 
    end 
    end 
end 

# John 
UserCustomAttribute.create(user_id: 1, custom_attribute_id: 1, value: 'no') 
UserCustomAttribute.create(user_id: 1, custom_attribute_id: 2, value: 'yes') 
UserCustomAttribute.create(user_id: 1, custom_attribute_id: 3, value: 4) 

# Jane 
UserCustomAttribute.create(user_id: 2, custom_attribute_id: 1, value: 'no') 
UserCustomAttribute.create(user_id: 2, custom_attribute_id: 2, value: 'no') 
UserCustomAttribute.create(user_id: 2, custom_attribute_id: 3, value: 0) 

Modelle:

class CustomAttribute < ActiveRecord::Base 
    has_many :user_custom_attributes, :dependent => :destroy 
    has_many :users, through: :user_custom_attributes 
end 

class UserCustomAttribute < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :custom_attribute 
end 

class User < ActiveRecord::Base 
    has_many :user_custom_attributes, :dependent => :destroy 
    has_many :custom_attributes, through: :user_custom_attributes 

    searchable do 
    text :first_name, :last_name, :email 
    end 
end 

Ich versuche, "value" zu ermöglichen, dynamisch zu sein, ob es sich um eine einfache boolean (0,1), string ("speedy") oder serialisiertes Array von Elementen ("---- Baseball- Football")

Ist es möglich, nach allen Benutzern zu suchen, die Kinder haben (z. B. "has_children" auf "yes" gesetzt)?

Zum Beispiel:/users fq [has_children] = yes

Auch wäre es möglich, für alle Benutzer mit Kindern zu suchen (z 'NUMBER_OF_CHILDREN' größer als 0)?

Wenn ja, wie würden Sie den 'durchsuchbaren' Block im User-Modell und im User.search-Block strukturieren?

Antwort

0

Der einfachste Weg, um zu tun, was Sie wollen, wäre zunächst die verschiedenen Arten von dynamischen Feldern, die Sie wollen (string, integer, boolean), durch Hinzufügen eines Attributs type: 'string', attribute_type: 'numeric ‚usw. Dann können Sie Sunspot dynamische Felder verwenden verschiedene Arten von dynamischen Daten suchen:

searchable do 
    dynamic_string :string_attributes do 
    user_custom_string_attributes.inject({}) do |hash, uca| 
     hash.merge(uca.custom_attribute.name.to_sym => uca.value) 
    end 
    end 

    dynamic_integer :numerical_attributes do 
    user_custom_numerical_attributes.inject({}) do |hash, nuca| 
     hash.merge(nuca.custom_attribute.name.to_sym => nuca.value.to_i) # just making sure it's an integer! 
    end 
    end 
end 

# Separate out the different types of attributes for different dynamic blocks 
# via methods like the one below. 

def user_custom_numerical_attributes 
    user_custom_attributes.where(attribute_type: 'numerical') 
end 

def user_custom_string_attributes 
    user_custom_attributes.where(attribute_type: 'string') 
end 

Dies wird Ihnen durchsuchbare‚string_attributes‘Objekte, die wie folgt aussehen {: has_children =>‚Nein‘} oder‘ numerical_attributes 'like {: Anzahl_von_Kindern => 2}.

Dann können Sie wie so mit einem Block suchen:

User.search do 
    dynamic :string_attributes do 
    with(:has_children, 'no') 
    end 

    dynamic :numerical_attributes do 
    with(:number_of_children).greater_than(0) 
    end 
end 

Sie dynamische Felder für so ziemlich jeden Datentyp außer Text erstellen können; Dafür musst du stattdessen string verwenden. Und sobald Sie Ihre dynamischen Felder eingerichtet haben, können Sie innerhalb des dynamic :field_name do Blocks eine der Nicht-Textsuchmethoden verwenden, die in den Beispielen in der Sunspot readme gezeigt werden.

Verwandte Themen