Adding search/order + Show need page + comments

This commit is contained in:
Nicolas VARROT 2015-12-04 14:34:12 +01:00
parent 22b86c191f
commit 1fd0e4c624
32 changed files with 504 additions and 149 deletions

View File

@ -70,3 +70,5 @@ gem "geocoder"
gem "paranoia", "~> 2.0"
gem 'workflow', '~> 1.2.0'
gem 'elasticsearch-model', git: 'git://github.com/elasticsearch/elasticsearch-rails.git'

View File

@ -1,3 +1,12 @@
GIT
remote: git://github.com/elasticsearch/elasticsearch-rails.git
revision: 5f32e484a6d0458f26dc9acfa9dd5fed4e5d6453
specs:
elasticsearch-model (0.1.8)
activesupport (> 3)
elasticsearch (> 0.4)
hashie
GEM
remote: https://rubygems.org/
specs:
@ -69,8 +78,18 @@ GEM
columnize (0.9.0)
debug_inspector (0.0.2)
debugger-linecache (1.2.0)
elasticsearch (1.0.14)
elasticsearch-api (= 1.0.14)
elasticsearch-transport (= 1.0.14)
elasticsearch-api (1.0.14)
multi_json
elasticsearch-transport (1.0.14)
faraday
multi_json
erubis (2.7.0)
execjs (2.3.0)
faraday (0.9.2)
multipart-post (>= 1.2, < 3)
formtastic (2.3.0)
actionpack (>= 3.0)
formtastic-bootstrap (3.0.0)
@ -87,6 +106,7 @@ GEM
haml (>= 3.1, < 5.0)
html2haml (>= 1.0.1)
railties (>= 4.0.1)
hashie (3.4.3)
highline (1.7.2)
hike (1.2.3)
html2haml (2.0.0)
@ -118,6 +138,7 @@ GEM
mini_portile (0.6.2)
minitest (5.5.1)
multi_json (1.10.1)
multipart-post (2.0.0)
mysql2 (0.3.18)
net-scp (1.2.1)
net-ssh (>= 2.6.5)
@ -228,6 +249,7 @@ DEPENDENCIES
capistrano (= 2.15.5)
carrierwave
coffee-rails (~> 4.1.0)
elasticsearch-model!
formtastic (= 2.3.0)
formtastic-bootstrap
geocoder

View File

@ -22,6 +22,7 @@
@flash_delay = ->
$("#flashs").find(".alert").each ->

View File

@ -0,0 +1,3 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/

View File

@ -0,0 +1,3 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/

View File

@ -0,0 +1,3 @@
// Place all the styles related to the public/messages controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

View File

@ -1,36 +1,98 @@
.btn-square{
border-radius: 0px;
}
.side-menu{
h3{
margin-top:0px;
}
}
.show-need{
position: relative;
.info{
color:rgb(163, 159, 159);
}
p.description{
margin-bottom:30px;
}
.message-item{
background: #eeeded;
}
.counters{
position:absolute;
left:0px;
bottom:0px;
padding-left:5px;
padding-bottom:5px;
.item{
display:inline;
margin-left:0px;
font-size:20px;
}
}
}
.need-item{
height: 150px;
background-color:#fff;
padding-top:30px;
p{
position:relative;
p.description{
font-size:12px;
color:rgb(163, 159, 159);
}
p.info{
font-size:10px;
color:rgb(163, 159, 159);
}
.counters{
position:absolute;
left:0px;
bottom:0px;
padding-left:5px;
padding-bottom:5px;
.item{
display:inline;
margin-left:10px;
font-size:18px;
}
}
span{
background-color: #ede8e8;
position:absolute;
padding:5px;
top:0px;
right:15px;
.time{
right:0px;
.info{
color:rgb(121, 120, 120);
text-align:right;
font-size:10px;
}
}
margin-bottom:30px;
h3{
margin-bottom:50px;
h4{
margin-top:0px;
margin-bottom:0px;
}
.btn{
border-radius: 0px;
position:absolute;
right:15px;
bottom:30px;
right:0px;
bottom:0px;
}
}

View File

@ -0,0 +1,3 @@
// Place all the styles related to the public/needs controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

View File

@ -40,7 +40,7 @@ class Admin::NeedsController < ApplicationController
flash[:notice] = "Besoin validé avec succès"
CustomerMailer.validate_need(@need).deliver
else
flash[:error] = "L'état actuel de ce besoin ne permet sa validation"
flash[:error] = "L'état actuel de ce besoin ne permet pas sa validation"
end
redirect_to admin_needs_path
end

View File

@ -0,0 +1,28 @@
class Public::MessagesController < ApplicationController
layout "public"
before_filter :auth_customer
def index
need = Need.find(params[:need_id])
end
def create
need = Need.find(params[:need_id])
@message = need.messages.create(comment_params)
@message.customer = current_customer
if(@message.save)
flash[:notice] = "Commentaire envoyé."
end
redirect_to public_need_path(need)
end
def comment_params
params.require(:message).permit(:content)
end
end

View File

@ -5,7 +5,58 @@ class Public::NeedsController < ApplicationController
before_filter :auth_customer
def index
# Get only public needs
@needs = Need.shared
# filters default value
params[:o] ||= 'created-desc'
# Include search in the query
if(params[:q] != '')
@needs = @needs.search(params[:q])
end
# Include order in the query
case params[:o]
when 'alpha-asc'
@needs = @needs.order(title: :asc)
when 'alpha-desc'
@needs = @needs.order(title: :desc)
when 'wishes-asc'
@needs = @needs.with_wishes_count.order('wishes_count ASC')
when 'wishes-desc'
@needs = @needs.with_wishes_count.order('wishes_count DESC')
when 'created-asc'
@needs = @needs.order(created_at: :asc)
when 'created-desc'
@needs = @needs.order(created_at: :desc)
when 'comments-asc'
@needs = @needs.with_messages_count.order('messages_count ASC')
when 'comments-desc'
@needs = @needs.with_messages_count.order('messages_count DESC')
end
# Paginate
@needs = @needs.page(params[:page]).per(6)
# Define order select options
@orders = {
"Les plus récents" => 'created-desc',
"Les plus anciens" => 'created-asc',
"Nombre d'intérêts décroissants" => 'wishes-desc',
"Nombre d'intérêts croissants" => 'wishes-asc' ,
"Nombre de commentaires décroissants" => 'comments-desc',
"Nombre de commentaires croissants" => 'comments-asc',
"Alphabétique (de A à Z)" => 'alpha-asc',
"Alphabétique (de Z à A)" => 'alpha-desc'
}
end
def new
@ -24,6 +75,13 @@ class Public::NeedsController < ApplicationController
@need = Need.find(params[:id])
end
def show
@need = Need.find(params[:id])
@comment = Message.new()
@comments = @need.messages.order(created_at: :desc).page params[:page]
end
def update
@need = Need.find(params[:id])
if @need.update_attributes(need_params)
@ -63,7 +121,7 @@ class Public::NeedsController < ApplicationController
flash[:notice] = "Vous avez signalé votre intérêt pour ce besoin"
else
@need.customers.delete(current_customer)
flash[:error] = "Vous n'être plus marqué comme intéressé par ce besoin"
flash[:error] = "Vous n'êtes maintenant plus intéressé par ce besoin"
end
redirect_to :back
end

View File

@ -0,0 +1,2 @@
module Public::MessagesHelper
end

View File

@ -0,0 +1,2 @@
module Public::NeedsHelper
end

View File

@ -3,7 +3,7 @@ class Customer < ActiveRecord::Base
# Relationships
has_many :owned_needs, foreign_key: 'author_id', class_name: 'Need'
has_many :wishes
has_many :wishes, dependent: :destroy
has_many :needs, -> { uniq }, through: :wishes
has_many :customer_favs
@ -141,6 +141,10 @@ class Customer < ActiveRecord::Base
end
def anonyme_nick
"Utilisateur#{id}"
end
def mlm_children_id_by_levels
self.mlm_detail_ids[:mlm_children_id_by_levels]
end

7
app/models/message.rb Normal file
View File

@ -0,0 +1,7 @@
class Message < ActiveRecord::Base
belongs_to :customer
belongs_to :need
paginates_per 5
validates :content, :presence => true, length: {within: 1..512}
end

View File

@ -1,21 +1,37 @@
require 'elasticsearch/model'
class Need < ActiveRecord::Base
include Workflow
include Elasticsearch::Model
include Elasticsearch::Model::Callbacks
scope :shared, -> {
where(state: ["verified", "negociating", "negociated", "failed"])
}
scope :top, -> { joins('left join wishes on wishes.need_id = needs.id')
scope :with_wishes_count, -> { joins('left join wishes on wishes.need_id = needs.id')
.select('needs.*, count(wishes.id) as wishes_count')
.group("needs.id")
.order("wishes_count DESC") }
}
scope :with_messages_count, -> { joins('left join messages on messages.need_id = needs.id')
.select('needs.*, count(messages.id) as messages_count')
.group("needs.id")
}
scope :search, -> (search) {
where('title LIKE ?', "%#{search}%")
}
workflow_column :state
max_paginates_per 10
acts_as_paranoid
has_many :wishes
has_many :wishes, dependent: :destroy
has_many :customers, -> { uniq }, through: :wishes
has_many :messages, dependent: :destroy
validates :title, :presence => true, length: {within: 4..128}
validates :description, presence: true, length: {maximum: 65535}
@ -46,7 +62,7 @@ class Need < ActiveRecord::Base
when 'created'
"En attente de validation"
when 'verified'
"Validé"
"Pas encore négocié"
when 'refused'
"Refusé"
when 'negociating'

View File

@ -9,7 +9,4 @@
%tr.submit_tr
%td=link_to "Annuler", admin_data_file_path(:id => @data_file.id, :manager => params[:manager], :multiple => params[:multiple]), :remote => true
%td
=form.submit "Sauvegarder"

View File

@ -10,5 +10,3 @@
%tbody
=render @needs
.pagination= paginate @needs

View File

@ -0,0 +1,6 @@
.white.padding.message-item
%h4= i(:"user") + " " + message.customer.anonyme_nick
%p.info=i(:"clock-o") + " Posté le #{message.created_at.strftime('%d/%m/%Y à %H:%M')}, il y a #{time_ago_in_words(message.created_at)}"
%p= message.content

View File

@ -1,16 +1,25 @@
.col-md-6
.padding.need-item
%h3=need.title.upcase
%h4
=link_to need.title.upcase, public_need_path(need)
%p.info=i(:"clock-o") + " Ajouté il y a #{time_ago_in_words(need.created_at)} par #{need.author.anonyme_nick}"
%span
.time= i(:"clock-o") + " Ajouté il y a #{time_ago_in_words(need.created_at)}"
.info=i(:"info-circle") + " " + need.human_state
%p=truncate(need.description, length: 100)
%p.description=truncate(need.description, length: 100)
.counters
.item=i(:"hand-paper-o") + " " + need.wishes.length.to_s
.item=i(:"comment-o") + " " + need.messages.length.to_s
-if(need.customers.include?(current_customer))
=link_to i(:"hand-grab-o") + " Ça ne m'intéresse plus", wish_public_need_path(need) , :class => "btn btn-danger pull-right"
=link_to i(:"check") + " Intéressé", wish_public_need_path(need) , :class => "btn btn-success pull-right"
-else
=link_to i(:"hand-paper-o") + " Ça m'intéresse", wish_public_need_path(need) , :class => "btn btn-success pull-right"
=link_to i(:"hand-paper-o") + " Ça m'intéresse !", wish_public_need_path(need) , :class => "btn btn-primary pull-right"
.clear

View File

@ -4,6 +4,25 @@
=render collection: @needs, partial: 'need_item', as: :need
.clear
.pagination= paginate @needs
.row.col-md-3
.white
%h3 Sidebar
.white.side-menu
= semantic_form_for :search, :html => {id: :search_form, :method => :get } do |f|
%h4 Recherche
= f.inputs do
= f.input :q, :as => :search, label: false, input_html: {value: params[:q], :name => 'q' }, placeholder: "Rechercher un besoin"
=f.submit "Rechercher", :class => "btn btn-primary pull-right"
.clear
%h4 Ordonner par
= f.inputs do
= f.input :o, as: :order, selected: params[:o], input_html: {:name => 'o' }, label: false, :include_blank => false , :as => :select, :collection => @orders
.clear
:javascript
$('#search_o').change(function(){$('#search_form').submit()})

View File

@ -0,0 +1,38 @@
.center.white
.show-need
%h1= @need.title.upcase
%p.info=i(:"clock-o") + " Ajouté il y a #{time_ago_in_words(@need.created_at)} par #{@need.author.anonyme_nick}"
%p.description= @need.description
.clear
.counters
-if(@need.wishes.length > 0)
.item=i(:"hand-paper-o") + " " + " #{pluralize(@need.wishes.length, 'Organisation')} #{"intéressé".pluralize(@need.wishes.length)} par ce besoin"
-else
.item=i(:"hand-paper-o") + " Aucune organisation n'est intéressé par ce besoin"
-if(@need.customers.include?(current_customer))
=link_to i(:"check") + " Intéressé", wish_public_need_path(@need) , :class => "btn btn-square btn-lg btn-success pull-right"
-else
=link_to i(:"hand-paper-o") + " Ça m'intéresse !", wish_public_need_path(@need) , :class => "btn btn-square btn-lg btn-primary pull-right"
.clear
%hr
= semantic_form_for [:public, @need, @comment ], :html => {id: :message_form, :method => :post } do |f|
%h4 Poster un commentaire
= f.inputs do
= f.input :content, as: :text, label: false, rows: 5, :input_html => {:style => "height:100px;"}
=f.submit "Envoyer", :class => "btn btn-square btn-primary pull-right"
.clear
%h3= i(:"comment-o") + " #{pluralize(@need.messages.count, 'Commentaire')} pour ce besoin"
=render collection: @comments, partial: 'message'
.pagination= paginate @comments

View File

@ -89,6 +89,7 @@ Rails.application.routes.draw do
get 'my_account/reconfirm', :as => "reconfirm_email"
resources :needs do
resources :messages
member do
get 'wish', as: 'wish'
end

View File

@ -0,0 +1,5 @@
class AddIndexToNeed < ActiveRecord::Migration
def change
add_index :needs, :title
end
end

View File

@ -0,0 +1,11 @@
class CreateMessages < ActiveRecord::Migration
def change
create_table :messages do |t|
t.timestamps null: false
t.references :customer
t.references :need
t.text :content
end
end
end

View File

@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20151202165807) do
ActiveRecord::Schema.define(version: 20151203185210) do
create_table "admins", force: :cascade do |t|
t.string "name", limit: 255
@ -382,6 +382,14 @@ ActiveRecord::Schema.define(version: 20151202165807) do
t.datetime "updated_at"
end
create_table "messages", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "customer_id", limit: 4
t.integer "need_id", limit: 4
t.text "content", limit: 65535
end
create_table "needs", force: :cascade do |t|
t.string "title", limit: 255
t.text "description", limit: 65535
@ -394,6 +402,7 @@ ActiveRecord::Schema.define(version: 20151202165807) do
add_index "needs", ["author_id"], name: "index_needs_on_author_id", using: :btree
add_index "needs", ["deleted_at"], name: "index_needs_on_deleted_at", using: :btree
add_index "needs", ["title"], name: "index_needs_on_title", using: :btree
create_table "newsgroups", force: :cascade do |t|
t.string "name", limit: 255

View File

@ -0,0 +1,7 @@
require 'test_helper'
class MessagesControllerTest < ActionController::TestCase
# test "the truth" do
# assert true
# end
end

View File

@ -0,0 +1,7 @@
require 'test_helper'
class Public::MessagesControllerTest < ActionController::TestCase
# test "the truth" do
# assert true
# end
end

View File

@ -0,0 +1,7 @@
require 'test_helper'
class Public::NeedsControllerTest < ActionController::TestCase
# test "the truth" do
# assert true
# end
end

View File

@ -0,0 +1,7 @@
require 'test_helper'
class PublicmessagesControllerTest < ActionController::TestCase
# test "the truth" do
# assert true
# end
end

11
test/fixtures/messages.yml vendored Normal file
View File

@ -0,0 +1,11 @@
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
# This model initially had no columns defined. If you add columns to the
# model remove the '{}' from the fixture names and add the columns immediately
# below each fixture, per the syntax in the comments below
#
one: {}
# column: value
#
two: {}
# column: value

View File

@ -0,0 +1,7 @@
require 'test_helper'
class MessageTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end