Skip to content

Commit

Permalink
Merge pull request #53 from andela-iamadi/search_enhance_contd
Browse files Browse the repository at this point in the history
Search Interface
  • Loading branch information
0sc committed Mar 14, 2016
2 parents f908388 + 8e9d7b3 commit b4f1fdf
Show file tree
Hide file tree
Showing 16 changed files with 154 additions and 16 deletions.
4 changes: 4 additions & 0 deletions app/controllers/questions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ def top_questions
render :index
end

def search
@questions = Question.search(params[:q])
end

private

def set_question
Expand Down
19 changes: 18 additions & 1 deletion app/models/concerns/searchable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,31 @@ module Searchable
include Elasticsearch::Model
# include Elasticsearch::Model::Callbacks

settings analysis: {
tokenizer: {
zhishi_edge_ngram_tokenizer: {
type: :edgeNGram,
min_gram: 3,
max_gram: 20,
token_chars: [ :letter, :digit ],
}
},
analyzer: {
zhishi_edge_ngram_analyzer: {
tokenizer: :zhishi_edge_ngram_tokenizer
},
}
}

after_touch :index_document_with_elastic_job
after_save :index_document_with_elastic_job
after_destroy :delete_document_from_elastic_with_job


def self.custom_index_name
[Rails.application.class.parent_name.downcase, Rails.env, model_name.collection.gsub('-', '')].join('_')
end

index_name custom_index_name
end

Expand Down
6 changes: 5 additions & 1 deletion app/models/concerns/votes_counter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ module VotesCounter
end

def votes_count
try(:total_votes) || votes_alternative
if respond_to? :total_votes
total_votes.to_i
else
votes_alternative
end
end

def votes_alternative
Expand Down
9 changes: 6 additions & 3 deletions app/models/tag.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class Tag < ActiveRecord::Base
include Searchable

validates :name, presence: true
has_many :resource_tags
has_many :questions, through: :resource_tags, source: :taggable, source_type: 'Question'
Expand All @@ -15,8 +17,9 @@ def self.get_tags_that_are(arg)
end
end

scope :search, -> (arg) do
val = arg ? where(arel_table[:name].matches("%#{arg}%")) : all
val.limit(5)
def as_indexed_json(options={})
self.as_json(
only: [:name]
)
end
end
4 changes: 3 additions & 1 deletion app/views/answers/_answer.json.jbuilder
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ json.answers(answers) do |answer|
json.partial! 'comments/default', data: answer
json.extract! answer, :question_id
json.extract! answer, :comments_count
json.partial! 'users/user', user: answer.user
json.user do
json.partial! 'users/user', user: answer.user
end
json.partial! 'comments/comment', comments: answer.comments
end
2 changes: 1 addition & 1 deletion app/views/comments/_comment.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1 +1 @@
json.comments @comment, partial: 'comments/default', as: :data
json.comments comments, partial: 'comments/default', as: :data
4 changes: 3 additions & 1 deletion app/views/comments/_default.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
json.(data, :id, :content, :votes_count, :created_at, :updated_at)
json.partial! 'users/user', user: data.user
json.user do
json.partial! 'users/user', user: data.user
end
4 changes: 3 additions & 1 deletion app/views/questions/_question.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
json.extract! question, :id, :title, :content, :votes_count ,:answers_count, :comments_count, :views, :created_at, :updated_at
json.partial! 'users/user', user: question.user
json.user do
json.partial! 'users/user', user: question.user
end
json.url question_url(question)
5 changes: 5 additions & 0 deletions app/views/questions/_search_result.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
json.extract! question, :id, :title, :content
json.user do
json.extract! question.user, :name, :email
end
json.url question_url(question.id)
3 changes: 3 additions & 0 deletions app/views/questions/search.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
json.questions(@questions) do |question|
json.partial! 'questions/search_result', question: question
end
1 change: 1 addition & 0 deletions app/views/questions/show.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
json.partial! 'questions/question', question: @question
json.partial! 'tags/tag', tags: @question.tags_to_a
json.partial! 'answers/answer', answers: @question.answers
# require 'pry' ; binding.pry
json.partial! 'comments/comment', comments: @question.comments
2 changes: 1 addition & 1 deletion app/views/users/_user.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1 +1 @@
json.user user, :id, :name, :email, :points, :image
json.extract! user, :id, :name, :email, :points, :image
4 changes: 3 additions & 1 deletion config/initializers/rack_timeout.rb
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
Rack::Timeout.timeout = 20 # seconds
if Rails.env.production?
Rack::Timeout.timeout = 20 # seconds
end
3 changes: 3 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
post '/validate_token', to: 'tokens#validate'

resources :questions, except: [:new, :edit] do
collection do
get :search
end
member do
get "recent_answers"
get "popular_answers"
Expand Down
36 changes: 35 additions & 1 deletion db/seeds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,40 @@
# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
# Mayor.create(name: 'Emanuel', city: cities.first)

FakeOmniAuth = Struct.new(:uid, :provider) do
Info = Struct.new(:name, :email, :image, :urls)
Credential = Struct.new(:token, :refresh_token)

def info
user_credentials = {
name: name,
email: Faker::Internet.email.gsub(/@.+/, '@andela.com'),
image: Faker::Avatar.image(name),
url: {
Google: Faker::Internet.url,
}
}
Info.new(*user_credentials.values)
end

def name
@name ||= Faker::Name.first_name
end

def credentials
token = SecureRandom.uuid.gsub('-', '')
Credential.new(token, nil)
end
end

24.times{
email = Faker::Internet.email.gsub(/@.+/, '@andela.com')
name = Faker::Name.first_name
id_number = Faker::IDNumber.valid

User.from_omniauth(FakeOmniAuth.new(id_number, 'google-oauth2'))
}

questions_list =[
["Requirements for Amity", "What are the requirements for geting accommodation at Amity" ],
["Renewing Amity Contract", "What happens at the expiration of the 6 months Amity resident agreement? Is it automatically renewed or are there processes to follow to get it renew. In same vein what steps are required if someone wants to leave before the expiration of the agreement."],
Expand All @@ -22,6 +56,6 @@
["What is the whole purpose of simulations project?", "What is the whole purpose of simulations project when the checkpoints do a better job of enabling fellows to learn things faster?"]
]

questions_list.each do |title, content, user_id|
questions_list.each do |title, content|
Question.create(title: title, content: content, user: User.order('RANDOM()').limit(1).first)
end
64 changes: 60 additions & 4 deletions docs/questions_endpoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ GET /questions/:id |question's id, auth_token in header| Returns the question wi
GET questions/top_questions | offset, limit ( both could be optional ), auth_token in header | Returns the questions matching the criteria for top questions or error message if any.
PUT questions/:id| question's id, update information(title, description), auth_token in header | Returns the updated question and all the information concerning it or error message if any.
DELETE questions/:id| question's id, auth_token in header | Returns a confirmation that the question has been deleted or error message if any.
GET questions/search | `q` which has the value of the params to search | Returns an array of questions, with a few things stripped off, such as association counts etc

## GET /questions/
Request
Expand All @@ -22,10 +23,8 @@ Status: 200
id: 1,
title: "what is Andela?",
user_id: 1,
tags: [{
matches: [ "operations", "Andela"],
}],
}
tags: [ "operations", "Andela"],
},
{
id: 2
title: "where is Amity?"
Expand Down Expand Up @@ -316,3 +315,60 @@ Status: 403
message: Error Message
}
```


## GET /questions/search
Request
```ruby
GET /questions/search?q=search+params
```
Response
```ruby
Status: 200
{
questions:[{
id: 1,
title: "what is Andela?",
content: "Andela has been said to be everything"
user: {
name: 'User Name',
email: '[email protected]',
},
tags: [ "operations", "Andela"],
url: 'http://zhishi.com/questions/1',
}
{
id: 2
title: "where is Amity?"
user_id: 12
tags: [{
matches: [ "operations", "Andela"],
}],
}
{
id: 3
title: "what is M55?"
user_id: 4
tags: [{
matches: [ "operations", "Andela"],
}],
}
{
id: 4
title: "What is DevOps?"
user_id: 12
tags: [{
matches: [ "operations", "Andela"],
}],
}
{
id: 5
title: "What is month one all about?"
user_id: 12
tags: [{
matches: [ "operations", "Andela"],
}],
}
]
}
```

0 comments on commit b4f1fdf

Please sign in to comment.