Modify search to include contacts
This commit is contained in:
parent
79117d1a46
commit
73ce521bb3
6 changed files with 37 additions and 24 deletions
|
|
@ -31,7 +31,8 @@ app.views.PublisherMention = app.views.SearchBase.extend({
|
||||||
app.views.SearchBase.prototype.initialize.call(this, {
|
app.views.SearchBase.prototype.initialize.call(this, {
|
||||||
typeaheadInput: this.typeaheadInput,
|
typeaheadInput: this.typeaheadInput,
|
||||||
customSearch: true,
|
customSearch: true,
|
||||||
autoselect: true
|
autoselect: true,
|
||||||
|
prefetch: true
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,6 @@ app.views.SearchBase = app.views.Base.extend({
|
||||||
return this.bloodhoundTokenizer(datum.name).concat(datum.handle);
|
return this.bloodhoundTokenizer(datum.name).concat(datum.handle);
|
||||||
}.bind(this),
|
}.bind(this),
|
||||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||||
prefetch: {
|
|
||||||
url: "/contacts.json",
|
|
||||||
transform: this.transformBloodhoundResponse,
|
|
||||||
cache: false
|
|
||||||
},
|
|
||||||
sufficient: 5
|
sufficient: 5
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -42,6 +37,14 @@ app.views.SearchBase = app.views.Base.extend({
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.prefetch) {
|
||||||
|
bloodhoundOptions.prefetch = {
|
||||||
|
url: "/contacts.json",
|
||||||
|
transform: this.transformBloodhoundResponse,
|
||||||
|
cache: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
this.bloodhound = new Bloodhound(bloodhoundOptions);
|
this.bloodhound = new Bloodhound(bloodhoundOptions);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,9 @@ class Person < ActiveRecord::Base
|
||||||
validates :serialized_public_key, :presence => true
|
validates :serialized_public_key, :presence => true
|
||||||
validates :diaspora_handle, :uniqueness => true
|
validates :diaspora_handle, :uniqueness => true
|
||||||
|
|
||||||
scope :searchable, -> { joins(:profile).where(:profiles => {:searchable => true}) }
|
scope :searchable, -> (user) {
|
||||||
|
joins(:profile).where("profiles.searchable = true OR contacts.user_id = ?", user.id)
|
||||||
|
}
|
||||||
scope :remote, -> { where('people.owner_id IS NULL') }
|
scope :remote, -> { where('people.owner_id IS NULL') }
|
||||||
scope :local, -> { where('people.owner_id IS NOT NULL') }
|
scope :local, -> { where('people.owner_id IS NOT NULL') }
|
||||||
scope :for_json, -> {
|
scope :for_json, -> {
|
||||||
|
|
@ -148,10 +150,9 @@ class Person < ActiveRecord::Base
|
||||||
|
|
||||||
sql, tokens = self.search_query_string(query)
|
sql, tokens = self.search_query_string(query)
|
||||||
|
|
||||||
Person.searchable.where(sql, *tokens).joins(
|
Person.searchable(user).where(sql, *tokens).joins(
|
||||||
"LEFT OUTER JOIN contacts ON contacts.user_id = #{user.id} AND contacts.person_id = people.id"
|
"LEFT OUTER JOIN contacts ON contacts.user_id = #{user.id} AND contacts.person_id = people.id"
|
||||||
).includes(:profile
|
).includes(:profile).order(search_order)
|
||||||
).order(search_order)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [Array<String>] postgreSQL and mysql deal with null values in orders differently, it seems.
|
# @return [Array<String>] postgreSQL and mysql deal with null values in orders differently, it seems.
|
||||||
|
|
|
||||||
|
|
@ -52,12 +52,6 @@ FactoryGirl.define do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
factory :searchable_person, :parent => :person do
|
|
||||||
after(:build) do |person|
|
|
||||||
person.profile = FactoryGirl.build(:profile, :person => person, :searchable => true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
factory :like do
|
factory :like do
|
||||||
association :author, :factory => :person
|
association :author, :factory => :person
|
||||||
association :target, :factory => :status_message
|
association :target, :factory => :status_message
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ describe("app.views.PublisherMention", function() {
|
||||||
expect(call.args[0].typeaheadInput.selector).toBe("#publisher .typeahead-mention-box");
|
expect(call.args[0].typeaheadInput.selector).toBe("#publisher .typeahead-mention-box");
|
||||||
expect(call.args[0].customSearch).toBeTruthy();
|
expect(call.args[0].customSearch).toBeTruthy();
|
||||||
expect(call.args[0].autoselect).toBeTruthy();
|
expect(call.args[0].autoselect).toBeTruthy();
|
||||||
|
expect(call.args[0].prefetch).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("calls bindTypeaheadEvents", function() {
|
it("calls bindTypeaheadEvents", function() {
|
||||||
|
|
|
||||||
|
|
@ -294,10 +294,11 @@ describe Person, :type => :model do
|
||||||
user_profile.last_name = "asdji"
|
user_profile.last_name = "asdji"
|
||||||
user_profile.save
|
user_profile.save
|
||||||
|
|
||||||
@robert_grimm = FactoryGirl.build(:searchable_person)
|
@robert_grimm = FactoryGirl.build(:person)
|
||||||
@eugene_weinstein = FactoryGirl.build(:searchable_person)
|
@eugene_weinstein = FactoryGirl.build(:person)
|
||||||
@yevgeniy_dodis = FactoryGirl.build(:searchable_person)
|
@yevgeniy_dodis = FactoryGirl.build(:person)
|
||||||
@casey_grippi = FactoryGirl.build(:searchable_person)
|
@casey_grippi = FactoryGirl.build(:person)
|
||||||
|
@invisible_person = FactoryGirl.build(:person)
|
||||||
|
|
||||||
@robert_grimm.profile.first_name = "Robert"
|
@robert_grimm.profile.first_name = "Robert"
|
||||||
@robert_grimm.profile.last_name = "Grimm"
|
@robert_grimm.profile.last_name = "Grimm"
|
||||||
|
|
@ -318,7 +319,14 @@ describe Person, :type => :model do
|
||||||
@casey_grippi.profile.last_name = "Grippi"
|
@casey_grippi.profile.last_name = "Grippi"
|
||||||
@casey_grippi.profile.save
|
@casey_grippi.profile.save
|
||||||
@casey_grippi.reload
|
@casey_grippi.reload
|
||||||
|
|
||||||
|
@invisible_person.profile.first_name = "Johnson"
|
||||||
|
@invisible_person.profile.last_name = "Invisible"
|
||||||
|
@invisible_person.profile.searchable = false
|
||||||
|
@invisible_person.profile.save
|
||||||
|
@invisible_person.reload
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'orders results by last name' do
|
it 'orders results by last name' do
|
||||||
@robert_grimm.profile.first_name = "AAA"
|
@robert_grimm.profile.first_name = "AAA"
|
||||||
@robert_grimm.profile.save!
|
@robert_grimm.profile.save!
|
||||||
|
|
@ -367,10 +375,15 @@ describe Person, :type => :model do
|
||||||
expect(people.first).to eq(@casey_grippi)
|
expect(people.first).to eq(@casey_grippi)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'only displays searchable people' do
|
it "doesn't display people that are neither searchable nor contacts" do
|
||||||
invisible_person = FactoryGirl.build(:person, :profile => FactoryGirl.build(:profile, :searchable => false, :first_name => "johnson"))
|
expect(Person.search("Johnson", @user)).to be_empty
|
||||||
expect(Person.search("johnson", @user)).not_to include invisible_person
|
end
|
||||||
expect(Person.search("", @user)).not_to include invisible_person
|
|
||||||
|
it "displays contacts that are not searchable" do
|
||||||
|
@user.contacts.create(person: @invisible_person, aspects: [@user.aspects.first])
|
||||||
|
people = Person.search("Johnson", @user)
|
||||||
|
expect(people.count).to eq(1)
|
||||||
|
expect(people.first).to eq(@invisible_person)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns results for Diaspora handles' do
|
it 'returns results for Diaspora handles' do
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue