Merge pull request #670 from metamaps/feature/explore-controller-simplify

[WIP test it] clean up routes and some controllers
This commit is contained in:
Devin Howard 2016-09-28 22:34:34 +08:00 committed by GitHub
commit d6a239d6b4
8 changed files with 317 additions and 302 deletions

View file

@ -1,19 +1,15 @@
# frozen_string_literal: true # frozen_string_literal: true
class ExploreController < ApplicationController class ExploreController < ApplicationController
before_action :require_authentication, only: [:mine, :shared, :starred]
before_action :authorize_explore before_action :authorize_explore
after_action :verify_authorized after_action :verify_authorized
after_action :verify_policy_scoped after_action :verify_policy_scoped
respond_to :html, :json, :csv respond_to :html, :json, :csv
# TODO: remove?
# autocomplete :map, :name, full: true, extra_data: [:user_id]
# GET /explore/active # GET /explore/active
def active def active
page = params[:page].present? ? params[:page] : 1 @maps = map_scope(Map)
@maps = policy_scope(Map).order('updated_at DESC')
.page(page).per(20)
respond_to do |format| respond_to do |format|
format.html do format.html do
@ -27,11 +23,7 @@ class ExploreController < ApplicationController
# GET /explore/featured # GET /explore/featured
def featured def featured
page = params[:page].present? ? params[:page] : 1 @maps = map_scope(Map.where(featured: true))
@maps = policy_scope(
Map.where('maps.featured = ? AND maps.permission != ?',
true, 'private')
).order('updated_at DESC').page(page).per(20)
respond_to do |format| respond_to do |format|
format.html { respond_with(@maps, @user) } format.html { respond_with(@maps, @user) }
@ -41,15 +33,7 @@ class ExploreController < ApplicationController
# GET /explore/mine # GET /explore/mine
def mine def mine
unless authenticated? @maps = map_scope(Map.where(user_id: current_user.id))
skip_policy_scope
return redirect_to explore_active_path
end
page = params[:page].present? ? params[:page] : 1
@maps = policy_scope(
Map.where('maps.user_id = ?', current_user.id)
).order('updated_at DESC').page(page).per(20)
respond_to do |format| respond_to do |format|
format.html { respond_with(@maps, @user) } format.html { respond_with(@maps, @user) }
@ -59,15 +43,7 @@ class ExploreController < ApplicationController
# GET /explore/shared # GET /explore/shared
def shared def shared
unless authenticated? @maps = map_scope(Map.where(id: current_user.shared_maps.map(&:id)))
skip_policy_scope
return redirect_to explore_active_path
end
page = params[:page].present? ? params[:page] : 1
@maps = policy_scope(
Map.where('maps.id IN (?)', current_user.shared_maps.map(&:id))
).order('updated_at DESC').page(page).per(20)
respond_to do |format| respond_to do |format|
format.html { respond_with(@maps, @user) } format.html { respond_with(@maps, @user) }
@ -77,16 +53,7 @@ class ExploreController < ApplicationController
# GET /explore/starred # GET /explore/starred
def starred def starred
unless authenticated? @maps = map_scope(Map.where(id: current_user.stars.map(&:map_id)))
skip_policy_scope
return redirect_to explore_active_path
end
page = params[:page].present? ? params[:page] : 1
stars = current_user.stars.map(&:map_id)
@maps = policy_scope(
Map.where('maps.id IN (?)', stars)
).order('updated_at DESC').page(page).per(20)
respond_to do |format| respond_to do |format|
format.html { respond_with(@maps, @user) } format.html { respond_with(@maps, @user) }
@ -96,10 +63,8 @@ class ExploreController < ApplicationController
# GET /explore/mapper/:id # GET /explore/mapper/:id
def mapper def mapper
page = params[:page].present? ? params[:page] : 1
@user = User.find(params[:id]) @user = User.find(params[:id])
@maps = policy_scope(Map.where(user: @user)) @maps = map_scope(Map.where(user: @user))
.order('updated_at DESC').page(page).per(20)
respond_to do |format| respond_to do |format|
format.html { respond_with(@maps, @user) } format.html { respond_with(@maps, @user) }
@ -109,7 +74,16 @@ class ExploreController < ApplicationController
private private
def map_scope(scope)
policy_scope(scope).order(updated_at: :desc).page(params[:page]).per(20)
end
def authorize_explore def authorize_explore
authorize :Explore authorize :Explore
end end
def require_authentication
# skip_policy_scope
redirect_to explore_active_path unless authenticated?
end
end end

View file

@ -1,172 +1,30 @@
# frozen_string_literal: true # frozen_string_literal: true
class MainController < ApplicationController class MainController < ApplicationController
include TopicsHelper before_action :authorize_main
include MapsHelper after_action :verify_authorized
include UsersHelper after_action :verify_policy_scoped, only: [:home]
include SynapsesHelper
after_action :verify_policy_scoped, except: [:requestinvite, :searchmappers] # GET /
respond_to :html, :json
# home page
def home def home
@maps = policy_scope(Map).order('updated_at DESC').page(1).per(20)
respond_to do |format| respond_to do |format|
format.html do format.html do
if !authenticated? if !authenticated?
render 'main/home' render 'main/home'
else else
@maps = policy_scope(Map).order(updated_at: :desc).page(1).per(20)
render 'explore/active' render 'explore/active'
end end
end end
end end
end end
### SEARCHING ### # GET /request
def requestinvite
# get /search/topics?term=SOMETERM
def searchtopics
term = params[:term]
user = params[:user] ? params[:user] : false
if term && !term.empty? && term.downcase[0..3] != 'map:' && term.downcase[0..6] != 'mapper:' && !term.casecmp('topic:').zero?
# remove "topic:" if appended at beginning
term = term[6..-1] if term.downcase[0..5] == 'topic:'
# if desc: search desc instead
desc = false
if term.downcase[0..4] == 'desc:'
term = term[5..-1]
desc = true
end
# if link: search link instead
link = false
if term.downcase[0..4] == 'link:'
term = term[5..-1]
link = true
end
# check whether there's a filter by metacode as part of the query
filterByMetacode = false
Metacode.all.each do |m|
lOne = m.name.length + 1
lTwo = m.name.length
if term.downcase[0..lTwo] == m.name.downcase + ':'
term = term[lOne..-1]
filterByMetacode = m
end
end
search = '%' + term.downcase + '%'
builder = policy_scope(Topic)
if filterByMetacode
if term == ''
builder = builder.none
else
builder = builder.where('LOWER("name") like ? OR
LOWER("desc") like ? OR
LOWER("link") like ?', search, search, search)
builder = builder.where(metacode_id: filterByMetacode.id)
end
elsif desc
builder = builder.where('LOWER("desc") like ?', search)
elsif link
builder = builder.where('LOWER("link") like ?', search)
else # regular case, just search the name
builder = builder.where('LOWER("name") like ? OR
LOWER("desc") like ? OR
LOWER("link") like ?', search, search, search)
end
builder = builder.where(user: user) if user
@topics = builder.order(:name)
else
@topics = []
end
render json: autocomplete_array_json(@topics)
end end
# get /search/maps?term=SOMETERM private
def searchmaps
term = params[:term]
user = params[:user] ? params[:user] : nil
if term && !term.empty? && term.downcase[0..5] != 'topic:' && term.downcase[0..6] != 'mapper:' && !term.casecmp('map:').zero? def authorize_main
authorize :Main
# remove "map:" if appended at beginning
term = term[4..-1] if term.downcase[0..3] == 'map:'
# if desc: search desc instead
desc = false
if term.downcase[0..4] == 'desc:'
term = term[5..-1]
desc = true
end
search = '%' + term.downcase + '%'
builder = policy_scope(Map)
builder = if desc
builder.where('LOWER("desc") like ?', search)
else
builder.where('LOWER("name") like ?', search)
end
builder = builder.where(user: user) if user
@maps = builder.order(:name)
else
@maps = []
end
render json: autocomplete_map_array_json(@maps)
end
# get /search/mappers?term=SOMETERM
def searchmappers
term = params[:term]
if term && !term.empty? && term.downcase[0..3] != 'map:' && term.downcase[0..5] != 'topic:' && !term.casecmp('mapper:').zero?
# remove "mapper:" if appended at beginning
term = term[7..-1] if term.downcase[0..6] == 'mapper:'
search = term.downcase + '%'
skip_policy_scope # TODO: builder = policy_scope(User)
builder = User.where('LOWER("name") like ?', search)
@mappers = builder.order(:name)
else
@mappers = []
end
render json: autocomplete_user_array_json(@mappers)
end
# get /search/synapses?term=SOMETERM OR
# get /search/synapses?topic1id=SOMEID&topic2id=SOMEID
def searchsynapses
term = params[:term]
topic1id = params[:topic1id]
topic2id = params[:topic2id]
if term && !term.empty?
@synapses = policy_scope(Synapse).where('LOWER("desc") like ?', '%' + term.downcase + '%').order('"desc"')
@synapses = @synapses.uniq(&:desc)
elsif topic1id && !topic1id.empty?
@one = policy_scope(Synapse).where('topic1_id = ? AND topic2_id = ?', topic1id, topic2id)
@two = policy_scope(Synapse).where('topic2_id = ? AND topic1_id = ?', topic1id, topic2id)
@synapses = @one + @two
@synapses.sort! { |s1, s2| s1.desc <=> s2.desc }.to_a
else
@synapses = []
end
# limit to 5 results
@synapses = @synapses.to_a.slice(0, 5)
render json: autocomplete_synapse_array_json(@synapses)
end end
end end

View file

@ -1,7 +1,9 @@
# frozen_string_literal: true # frozen_string_literal: true
class MapsController < ApplicationController class MapsController < ApplicationController
before_action :require_user, only: [:create, :update, :destroy, :access, :events, :screenshot, :star, :unstar] before_action :require_user, only: [:create, :update, :destroy, :access, :events,
before_action :set_map, only: [:show, :update, :destroy, :access, :contains, :events, :export, :screenshot, :star, :unstar] :screenshot]
before_action :set_map, only: [:show, :update, :destroy, :access, :contains,
:events, :export, :screenshot]
after_action :verify_authorized after_action :verify_authorized
autocomplete :map, :name, full: true, extra_data: [:user_id] autocomplete :map, :name, full: true, extra_data: [:user_id]
@ -18,7 +20,8 @@ class MapsController < ApplicationController
@allmessages = @map.messages.sort_by(&:created_at) @allmessages = @map.messages.sort_by(&:created_at)
@allstars = @map.stars @allstars = @map.stars
respond_with(@allmappers, @allcollaborators, @allmappings, @allsynapses, @alltopics, @allmessages, @allstars, @map) respond_with(@allmappers, @allcollaborators, @allmappings, @allsynapses,
@alltopics, @allmessages, @allstars, @map)
end end
format.json { render json: @map } format.json { render json: @map }
format.csv { redirect_to action: :export, format: :csv } format.csv { redirect_to action: :export, format: :csv }
@ -41,10 +44,10 @@ class MapsController < ApplicationController
# POST maps # POST maps
def create def create
@user = current_user
@map = Map.new(create_map_params) @map = Map.new(create_map_params)
@map.user = @user @map.user = current_user
@map.arranged = false @map.arranged = false
authorize @map
if params[:topicsToMap].present? if params[:topicsToMap].present?
create_topics! create_topics!
@ -52,8 +55,6 @@ class MapsController < ApplicationController
@map.arranged = true @map.arranged = true
end end
authorize @map
respond_to do |format| respond_to do |format|
if @map.save if @map.save
format.json { render json: @map } format.json { render json: @map }
@ -89,8 +90,9 @@ class MapsController < ApplicationController
def access def access
user_ids = params[:access] || [] user_ids = params[:access] || []
added = @map.add_new_collaborators(user_ids) @map.add_new_collaborators(user_ids).each do |user_id|
added.each do |user_id| # add_new_collaborators returns array of added users,
# who we then send an email to
MapMailer.invite_to_edit_email(@map, current_user, User.find(user_id)).deliver_later MapMailer.invite_to_edit_email(@map, current_user, User.find(user_id)).deliver_later
end end
@map.remove_old_collaborators(user_ids) @map.remove_old_collaborators(user_ids)
@ -148,29 +150,6 @@ class MapsController < ApplicationController
end end
end end
# POST maps/:id/star
def star
star = Star.find_or_create_by(map_id: @map.id, user_id: current_user.id)
respond_to do |format|
format.json do
render json: { message: 'Successfully starred map' }
end
end
end
# POST maps/:id/unstar
def unstar
star = Star.find_by(map_id: @map.id, user_id: current_user.id)
star&.delete
respond_to do |format|
format.json do
render json: { message: 'Successfully unstarred map' }
end
end
end
private private
def set_map def set_map
@ -187,29 +166,20 @@ class MapsController < ApplicationController
end end
def create_topics! def create_topics!
topics = params[:topicsToMap] params[:topicsToMap].split(',').each do |topic|
topics = topics.split(',')
topics.each do |topic|
topic = topic.split('/') topic = topic.split('/')
mapping = Mapping.new mapping = Mapping.new(map: @map, user: current_user,
mapping.map = @map mappable: Topic.find(topic[0]),
mapping.user = @user xloc: topic[1], yloc: topic[2])
mapping.mappable = Topic.find(topic[0])
mapping.xloc = topic[1]
mapping.yloc = topic[2]
authorize mapping, :create? authorize mapping, :create?
mapping.save mapping.save
end end
end end
def create_synapses! def create_synapses!
@synAll = params[:synapsesToMap] params[:synapsesToMap].split(',').each do |synapse_id|
@synAll = @synAll.split(',') mapping = Mapping.new(map: @map, user: current_user,
@synAll.each do |synapse_id| mappable: Synapse.find(synapse_id))
mapping = Mapping.new
mapping.map = @map
mapping.user = @user
mapping.mappable = Synapse.find(synapse_id)
authorize mapping, :create? authorize mapping, :create?
mapping.save mapping.save
end end

View file

@ -0,0 +1,162 @@
# frozen_string_literal: true
class MainController < ApplicationController
include TopicsHelper
include MapsHelper
include UsersHelper
include SynapsesHelper
before_action :authorize_search
after_action :verify_authorized
after_action :verify_policy_scoped, only: [:maps, :mappers, :synapses, :topics]
# get /search/topics?term=SOMETERM
def topics
term = params[:term]
user = params[:user] ? params[:user] : false
if term && !term.empty? && term.downcase[0..3] != 'map:' && term.downcase[0..6] != 'mapper:' && !term.casecmp('topic:').zero?
# remove "topic:" if appended at beginning
term = term[6..-1] if term.downcase[0..5] == 'topic:'
# if desc: search desc instead
desc = false
if term.downcase[0..4] == 'desc:'
term = term[5..-1]
desc = true
end
# if link: search link instead
link = false
if term.downcase[0..4] == 'link:'
term = term[5..-1]
link = true
end
# check whether there's a filter by metacode as part of the query
filterByMetacode = false
Metacode.all.each do |m|
lOne = m.name.length + 1
lTwo = m.name.length
if term.downcase[0..lTwo] == m.name.downcase + ':'
term = term[lOne..-1]
filterByMetacode = m
end
end
search = '%' + term.downcase + '%'
builder = policy_scope(Topic)
if filterByMetacode
if term == ''
builder = builder.none
else
builder = builder.where('LOWER("name") like ? OR
LOWER("desc") like ? OR
LOWER("link") like ?', search, search, search)
builder = builder.where(metacode_id: filterByMetacode.id)
end
elsif desc
builder = builder.where('LOWER("desc") like ?', search)
elsif link
builder = builder.where('LOWER("link") like ?', search)
else # regular case, just search the name
builder = builder.where('LOWER("name") like ? OR
LOWER("desc") like ? OR
LOWER("link") like ?', search, search, search)
end
builder = builder.where(user: user) if user
@topics = builder.order(:name)
else
@topics = []
end
render json: autocomplete_array_json(@topics)
end
# get /search/maps?term=SOMETERM
def maps
term = params[:term]
user = params[:user] ? params[:user] : nil
if term && !term.empty? && term.downcase[0..5] != 'topic:' && term.downcase[0..6] != 'mapper:' && !term.casecmp('map:').zero?
# remove "map:" if appended at beginning
term = term[4..-1] if term.downcase[0..3] == 'map:'
# if desc: search desc instead
desc = false
if term.downcase[0..4] == 'desc:'
term = term[5..-1]
desc = true
end
search = '%' + term.downcase + '%'
builder = policy_scope(Map)
builder = if desc
builder.where('LOWER("desc") like ?', search)
else
builder.where('LOWER("name") like ?', search)
end
builder = builder.where(user: user) if user
@maps = builder.order(:name)
else
@maps = []
end
render json: autocomplete_map_array_json(@maps)
end
# get /search/mappers?term=SOMETERM
def mappers
term = params[:term]
if term && !term.empty? && term.downcase[0..3] != 'map:' && term.downcase[0..5] != 'topic:' && !term.casecmp('mapper:').zero?
# remove "mapper:" if appended at beginning
term = term[7..-1] if term.downcase[0..6] == 'mapper:'
search = term.downcase + '%'
skip_policy_scope # TODO: builder = policy_scope(User)
builder = User.where('LOWER("name") like ?', search)
@mappers = builder.order(:name)
else
@mappers = []
end
render json: autocomplete_user_array_json(@mappers)
end
# get /search/synapses?term=SOMETERM OR
# get /search/synapses?topic1id=SOMEID&topic2id=SOMEID
def synapses
term = params[:term]
topic1id = params[:topic1id]
topic2id = params[:topic2id]
if term && !term.empty?
@synapses = policy_scope(Synapse).where('LOWER("desc") like ?', '%' + term.downcase + '%').order('"desc"')
@synapses = @synapses.uniq(&:desc)
elsif topic1id && !topic1id.empty?
@one = policy_scope(Synapse).where(topic1_id: topic1id, topic2_id: topic2id)
@two = policy_scope(Synapse).where(topic2_id: topic1id, topic1_id: topic2id)
@synapses = @one + @two
@synapses.sort! { |s1, s2| s1.desc <=> s2.desc }.to_a
else
@synapses = []
end
# limit to 5 results
@synapses = @synapses.to_a.slice(0, 5)
render json: autocomplete_synapse_array_json(@synapses)
end
private
def authorize_search
authorize :Search
end
end

View file

@ -0,0 +1,37 @@
# frozen_string_literal: true
class StarsController < ApplicationController
before_action :require_user
before_action :set_map
after_action :verify_authorized
# POST maps/:id/star
def create
authorize @map, :star?
Star.find_or_create_by(map_id: @map.id, user_id: current_user.id)
respond_to do |format|
format.json do
render json: { message: 'Successfully starred map' }
end
end
end
# POST maps/:id/unstar
def destroy
authorize @map, :unstar?
star = Star.find_by(map_id: @map.id, user_id: current_user.id)
star&.delete
respond_to do |format|
format.json do
render json: { message: 'Successfully unstarred map' }
end
end
end
private
def set_map
@map = Map.find(params[:id])
end
end

View file

@ -1,27 +1,10 @@
# frozen_string_literal: true # frozen_string_literal: true
class MainPolicy < ApplicationPolicy class MainPolicy < ApplicationPolicy
def initialize(user, _record)
@user = user
@record = nil
end
def home? def home?
true true
end end
def searchtopics? def requestinvite?
true
end
def searchmaps?
true
end
def searchmappers?
true
end
def searchsynapses?
true true
end end
end end

View file

@ -0,0 +1,18 @@
# frozen_string_literal: true
class SearchPolicy < ApplicationPolicy
def topics?
true
end
def maps?
true
end
def mappers?
true
end
def synapses?
true
end
end

View file

@ -1,14 +1,64 @@
# frozen_string_literal: true # frozen_string_literal: true
Metamaps::Application.routes.draw do Metamaps::Application.routes.draw do
use_doorkeeper use_doorkeeper
root to: 'main#home', via: :get
root to: 'main#home', via: :get
get 'request', to: 'main#requestinvite', as: :request get 'request', to: 'main#requestinvite', as: :request
get 'search/topics', to: 'main#searchtopics', as: :searchtopics namespace :explore do
get 'search/maps', to: 'main#searchmaps', as: :searchmaps get 'active'
get 'search/mappers', to: 'main#searchmappers', as: :searchmappers get 'featured'
get 'search/synapses', to: 'main#searchsynapses', as: :searchsynapses get 'mine'
get 'shared'
get 'starred'
get 'mapper/:id', action: 'mapper'
end
resources :maps, except: [:index, :edit] do
member do
get :export
post 'events/:event', action: :events
get :contains
post :upload_screenshot, action: :screenshot
post :access, default: { format: :json }
post :star, to: 'stars#create', defaults: { format: :json }
post :unstar, to: 'stars#destroy', defaults: { format: :json }
end
end
resources :mappings, except: [:index, :new, :edit]
resources :messages, only: [:show, :create, :update, :destroy]
resources :metacode_sets, except: [:show]
resources :metacodes, except: [:destroy]
get 'metacodes/:name', to: 'metacodes#show'
namespace :search do
get :topics
get :maps
get :mappers
get :synapses
end
resources :synapses, except: [:index, :new, :edit]
resources :topics, except: [:index, :new, :edit] do
get :autocomplete_topic
member do
get :network
get :relative_numbers
get :relatives
end
end
resources :users, except: [:index, :destroy] do
member do
get :details
end
end
post 'user/updatemetacodes', to: 'users#updatemetacodes', as: :updatemetacodes
namespace :api, path: '/api', default: { format: :json } do namespace :api, path: '/api', default: { format: :json } do
namespace :v2, path: '/v2' do namespace :v2, path: '/v2' do
@ -33,39 +83,6 @@ Metamaps::Application.routes.draw do
end end
end end
resources :messages, only: [:show, :create, :update, :destroy]
resources :mappings, except: [:index, :new, :edit]
resources :metacode_sets, except: [:show]
resources :metacodes, except: [:destroy]
get 'metacodes/:name', to: 'metacodes#show'
resources :synapses, except: [:index, :new, :edit]
resources :topics, except: [:index, :new, :edit] do
get :autocomplete_topic, on: :collection
end
get 'topics/:id/network', to: 'topics#network', as: :network
get 'topics/:id/relative_numbers', to: 'topics#relative_numbers', as: :relative_numbers
get 'topics/:id/relatives', to: 'topics#relatives', as: :relatives
resources :maps, except: [:index, :edit]
get 'maps/:id/export', to: 'maps#export'
post 'maps/:id/events/:event', to: 'maps#events'
get 'maps/:id/contains', to: 'maps#contains', as: :contains
post 'maps/:id/upload_screenshot', to: 'maps#screenshot', as: :screenshot
post 'maps/:id/access', to: 'maps#access', as: :access, defaults: { format: :json }
post 'maps/:id/star', to: 'maps#star', defaults: { format: :json }
post 'maps/:id/unstar', to: 'maps#unstar', defaults: { format: :json }
namespace :explore do
get 'active'
get 'featured'
get 'mine'
get 'shared'
get 'starred'
get 'mapper/:id', action: 'mapper'
end
devise_for :users, skip: :sessions, controllers: { devise_for :users, skip: :sessions, controllers: {
registrations: 'users/registrations', registrations: 'users/registrations',
passwords: 'users/passwords', passwords: 'users/passwords',
@ -79,10 +96,6 @@ Metamaps::Application.routes.draw do
get 'join' => 'devise/registrations#new', :as => :new_user_registration_path get 'join' => 'devise/registrations#new', :as => :new_user_registration_path
end end
get 'users/:id/details', to: 'users#details', as: :details
post 'user/updatemetacodes', to: 'users#updatemetacodes', as: :updatemetacodes
resources :users, except: [:index, :destroy]
namespace :hacks do namespace :hacks do
get 'load_url_title' get 'load_url_title'
end end