Save 36% for Black Friday! Learn more

Ben John Bagley

Joined

3,260 Experience
22 Lessons Completed
1 Question Solved

Activity

Posted in How do I implement advanced search?

Hi all,

I'm currently working on re-building a search feature, we have a basic search and an advanced search, I have a basic text search form working for the name, however, I can't seem to get an option based search working.

Here's what I have so far.

Scenario:

I need to be able to select the dropdown option and then enter my search term, here is what my form looks like

My form looks like this

<%= form_tag contacts_path, method: :get do %>
  <div class='l-inline-row-block'>
    <div class='l-inline-col'>
      <%= select_tag(:qs, options_for_select(['name', 'customers', 'suppliers', 'tags'], selected: params[:qs])) %>
    </div>

    <div class='l-inline-col'>
      <%= search_field_tag :search, params[:search] %>
    </div>

    <div class='l-inline-col'>
      <%= submit_tag submit_text, { class: 'no_print' } %>
    </div>
  </div>
<% end %>

I have the following in the controller index method

 @contacts = Contact.search(params[:qs], params[:search])

and the following in the model

SEARCHABLE_FIELDS = [
  'name',
  'customers_name',
  'suppliers_name',
  'tags'
]

def self.search(field, query)
  if field.present? && query.present? && SEARCHABLE_FIELDS.include?(field)
    where(arel_attribute(field).matches("%#{query}%"))
  else
    all
  end
end

Here is the db structure:

  create_table "contacts", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.integer  "customer_account_id"
    t.integer  "supplier_account_id"
    t.string   "name"
    t.string   "salutation"
    t.string   "title"
    t.string   "phone"
    t.string   "mobile"
    t.string   "business_email"
    t.string   "private_email"
    t.date     "date_of_birth"
    t.string   "spouse"
    t.string   "address_1"
    t.string   "address_2"
    t.string   "address_3"
    t.string   "address_4"
    t.string   "postcode"
    t.text     "other_information",   limit: 65535
    t.integer  "created_by"
    t.integer  "updated_by"
    t.string   "contact_type"
    t.integer  "assigned_to"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "company_name"
    t.string   "web_address"
    t.string   "second_phone"
    t.integer  "prospect_strength"
    t.boolean  "obsolete"
    t.string   "url"
    t.index ["obsolete"], name: "index_contacts_on_obsolete", using: :btree
  end

create_table "accounts", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
  t.string   "short_name",        limit: 9
  t.string   "name"
  t.string   "type"
  t.string   "child_type"
  t.integer  "parent_id"
  t.integer  "position"
  t.datetime "created_at"
  t.datetime "updated_at"
  t.decimal  "value",                       precision: 11, scale: 2, default: "0.0"
  t.boolean  "fixed",                                                default: false
  t.boolean  "allow_new_child",                                      default: false
  t.integer  "created_by"
  t.integer  "updated_by"
  t.boolean  "disabled",                                             default: false
  t.boolean  "locked",                                               default: false
  t.boolean  "restricted",                                           default: false
  t.string   "account_section"
  t.string   "description"
  t.boolean  "is_budget_account",                                    default: true
  t.boolean  "is_budget_enabled",                                    default: false
  t.integer  "sequence"
  t.index ["type"], name: "index_accounts_on_type", using: :btree
end

were using acts_as_taggable for the tags which need to be searchable.

Here is the current method that the previous search uses if this helps

def quick_search_fields
  @quick_search_fields = [
    {
      col_name: 'name',
      title: 'name',
      column_names: ['contacts.name']
    },
    {
      col_name: 'customer_name',
      title: 'customer',
      search_tables: [:customer],
      column_names: ['accounts.name']
    },
    {
      col_name: 'supplier_name',
      title: 'supplier',
      search_tables: [:supplier],
      column_names: ['accounts.name']
    },
    {
      col_name: 'tags',
      title: 'tags',
      tags: true,
      tagged: Contact
    }
  ]
end

This is the error I'm getting:

Mysql2::Error: Unknown column 'contacts.tags' in 'where clause': SELECT  `contacts`.* FROM `contacts` WHERE (`contacts`.`tags` LIKE '%4%') ORDER BY id asc LIMIT 20 OFFSET 0

The advanced search tab looks like this, I'm trying not to use a gem if possible as I want to learn how best to do this, obviously there is a lot of options but I want to focus on the basic option based search for now.

To me though it's a little odd to search the accounts table as that actually doesn't do anything so for now I only want to get the name and tag options working.

I have set up and deployed an application using Capistrano and set up the server and ngnix config file, however, I'm still seeing the `Welcome to ngnix` welcome screen.

Here is what I have in the `/etc/nginx/sites-enabled/default` file

server {
    listen 80;
    listen [::]:80 ipv6only=on;
    
    server_name IP;
    passenger_enabled on;
    rails_env    production;
    root         /home/poladmin/poetry-out-loud-v2/current/public/;
    
    # redirect server error pages to the static page /50x.html
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
}

But as I said when I go to the server IP all I see is

https://i.gyazo.com/f925d16bdc933b8f90767be17cc46f2b.png

I have followed the https://gorails.com/deploy/ubuntu/16.04 tutorial, I am using puma locally and passenger in production, the app is successfully being deployed to the server but I'm not seeing it live.

P.S. I have ran sudo service nginx restart

Posted in Chartkick and impressionist gem render not working

This is a personal project and not a paid gig.

So I'll give it a shot, if not I'll think of something else.

Posted in Chartkick and impressionist gem render not working

Yeah so I still can't get this working, the example provided is if the raffles were a seperate entity to the dashboard and not actually attached to anything.

I don't believe that passing in the data that I'm trying to pass needs x amount of various other files in need for this to work, as the data is already there and can be shown in the graph.

screenshot of data showing the 222 impressions is spread across the week and not just on the one day.

It's not a diffult thing I'm trying to do here, I can get the data to pass but not actually take into account the day, hour etc i.e. 20 impressions on Thurday and 40 impressions on Friday, they just go into the one bar, not multiple as shown in the Chartkick documentation. I have tried their examples, nothing.

I've followed the chartkick documentation and nothing seems to be working here.

Anything else you can provide here, would be appricated, if not I may as well discontinue the project until a later date or all together.

Posted in Chartkick and impressionist gem render not working

Forgot to restart the server, oops.

Ok I get this screenshot the impressions are been show as 2017, not the actual count, plus I'm not seeing the time actually being shown in the axis.

So for example showing the amount of impressions on that raffle per raffle or on all raffles by the hour.

I can't seem to be able to use .goup(:title) or anything after Dashboard::Raffle.first.raffle_impressions_count

Posted in Chartkick and impressionist gem render not working

So I have updated the code to the above and now a few errors are being flagged

error #1
error #2
error #3

I think were getting close.

Posted in Chartkick and impressionist gem render not working

So I've set this up but I get the following error

Here is the file struture with the code in the files above screenshot

Posted in Chartkick and impressionist gem render not working

So I've had a play around and I have something like this

<%= area_chart raffle_impressions, refresh: 60, colors: ["#62518C", "#F7AE07"] %>

raffle.rb

class Dashboard::Raffle < ApplicationRecord
  is_impressionable :counter_cache => true, :column_name => :impressions_count, :unique => :all
  has_many :users

  def raffle_impressions_count
    RaffleImpressions.raffle_impressions_count(self)
  end
end

module RaffleImpressions
  def raffle_impressions_count(Dashboard::Raffle)
    raffles = Dashboard::Raffle.all
    time_ranges = [['2017-12-08 08:00:00 -0600', '2017-12-08 09:00:00 -0600'], ['2017-12-08 09:00:00 -0600', '2017-12-08 10:00:00 -0600']]

    raffles_array = [] # don't need raffles_hash, instead just an array to load

    raffles.each do |raffle|
      impressions = []
      time_ranges.each do |time|
        impressions << [[ time[0], time[1] ], raffle.impressionist_count(start_date: time[0], end_date: time[1]) ]
      end

      raffles_array << { name => raffle.title, data => impressions }
    end

    return raffles_array
  end
end

But I am recieveing an error screenshot error

Posted in Chartkick and impressionist gem render not working

Ok so how would I go about getting the data into the area chart, do I put that code into a controller or how to I go about testing and using that code?

Posted in Chartkick and impressionist gem render not working

This is what I get

irb(main):001:0> Dashboard::Raffle.first.impressionist_count(start_date: Time.now - 1.hour, end_date: Time.now)
  Dashboard::Raffle Load (0.4ms)  SELECT  "dashboard_raffles".* FROM "dashboard_raffles" ORDER BY "dashboard_raffles"."id" ASC LIMIT $1  [["LIMIT", 1]]
   (1.5ms)  SELECT COUNT(DISTINCT "impressions"."request_hash") FROM "impressions" WHERE "impressions"."impressionable_id" = $1 AND "impressions"."impressionable_type" = $2 AND (created_at >= '2017-12-08 13:07:55.321801' and created_at <= '2017-12-08 14:07:55.321866')  [["impressionable_id", 1], ["impressionable_type", "Dashboard::Raffle"]]
=> 0

Posted in Chartkick and impressionist gem render not working

So I have tried this

<%= area_chart Dashboard::Raffle.first.impressionist_count(start_date: Time.now - 1.hour, end_date: Time.now), refresh: 60, colors: ["#62518C", "#F7AE07"] %>

and I get the following screenshot no data is passing, I would like to eventually pass all raffles impressions into the graph by hour.

Any ideas.

Posted in Chartkick and impressionist gem render not working

Hey,

Quick question.

I'm trying to target group_by_minute or group_by_hour and it just seems to be going on the same line in the graph.

Here is the line of code

<%= area_chart Dashboard::Raffle.group(:title).group_by_minute(:created_at).maximum(:impressions_count), colors: ["#62518C", "#F7AE07"] %>

I get this screenshot see how the value is at 180?

I have increased the counter to 211 screenshot but everything is staying on the one line and it's showing the wrong time, so the time or anything like that isn't been taken into account like so screenshot.

Any tips?

Posted in Chartkick and impressionist gem render not working

Got it

screenshot screenshot #2

using the following line

<%= area_chart Dashboard::Raffle.group(:title).group_by_hour(:created_at).maximum(:impressions_count), min: nil, refresh: 10, colors: ["#62518C", "#F7AE07"] %>

Thank you for all your help.

Posted in Chartkick and impressionist gem render not working

So I had a play around with the documentation.

I got this to work

def impressions
  render json: Dashboard::Raffle.all.group(:impressions_count).count
end

screenshot

If I do

render json: Dashboard::Raffle.all.group_by_day(:impressions_count).count

it doesn't work, so I'm guessing something group_by_day doesn't work even though I have the gem 'groupdate' installed, strange.

I need to have a play around and make the graph more readable, with the labels etc.

Posted in Chartkick and impressionist gem render not working

Here is what I get now

screenshot

Posted in Chartkick and impressionist gem render not working

Here is everything

charts_controller.rb

class ChartsController < ApplicationController
  def impressions
    # render json: Dashboard::Raffle.all.impressions_count.group_by_day(:created_at).count
    render json: impressions = Dashboard::Raffle.all.map{ |r| r.impressions }.flatten
  end
end

raffle.rb

class Dashboard::Raffle < ApplicationRecord
  is_impressionable :counter_cache => true, :column_name => :impressions_count, :unique => :all
end

raffles_controller.rb

class Dashboard::RafflesController < ApplicationController
  before_action :set_dashboard_raffle, only: [:show, :edit, :update, :destroy]

  def show
    @dashboard_raffle = Dashboard::Raffle.find(params[:id])
    impressionist(@dashboard_raffle)
  end

  def new
    @dashboard_raffle = Dashboard::Raffle.new
  end

  def edit
  end

  def create
    @dashboard_raffle = Dashboard::Raffle.new(dashboard_raffle_params)

    if @dashboard_raffle.save
      redirect_to @dashboard_raffle, notice: 'Raffle was successfully created.'
    else
      render :new
    end
  end

  def update
    if @dashboard_raffle.update(dashboard_raffle_params)
      redirect_to @dashboard_raffle, notice: 'Raffle was successfully updated.'
    else
      render :edit
    end
  end

  def destroy
    @dashboard_raffle.destroy
    redirect_to dashboard_raffles_url, notice: 'Raffle was successfully destroyed.'
  end

  private

    def set_dashboard_raffle
      @dashboard_raffle = Dashboard::Raffle.find(params[:id])
    end

    def dashboard_raffle_params
      params.require(:dashboard_raffle).permit(:title, :organisation, :prizes, :raise_limit, :deadline, :max_entires, :ticket_price, :raffle_limit)
    end
end

dashboard_controller.rb

class DashboardController < ApplicationController
  before_action :authenticate_user!

  def index
    @dashboard_raffles = Dashboard::Raffle.all
  end
end

routes.rb

Rails.application.routes.draw do
  namespace :dashboard do
    resources :raffles
  end
  devise_for :users
  root 'welcome#index'

  get 'about', to: 'pages#about', as: 'about'

  # Dashboard Routes
  get 'dashboard', to: 'dashboard#index', as: 'dashboard'

  namespace :charts do
    get 'impressions'
  end
end

Hopefully somewhere in that file outputs is what you need.

Posted in Chartkick and impressionist gem render not working

Here is the _overview.html.erb file

<section class="content active" id="overview">
  <section class="grid text-center">
    <section class="grid__col grid__col--1-of-4 box">
      <h3>Total Payments</h3>
      <span>600</span>
    </section>
    <section class="grid__col grid__col--1-of-4 box">
      <h3>Total Raised (All raffles)</h3>
      <span>£2,500.00</span>
    </section>
    <section class="grid__col grid__col--1-of-4 box">
      <h3>Total Entries</h3>
      <span>142</span>
    </section>
  </section> <!-- end three grid -->

  <section class="grid text-center">
    <section class="grid__col grid__col--1-of-2">
      <h3>Overall Impressions</h3>
      <%= area_chart charts_impressions_path, colors: ["#7123D1"] %>
    </section>
    <section class="grid__col grid__col--1-of-2">
      <h3>Total Impressions</h3>
      <%= area_chart charts_impressions_path %>
    </section>
  </section>
</section>

I have two graphs here doing the same thing, I will change the second graph but I do want to get at least the impressions data flowing.

Also here is a screenshot of the file structure

Posted in Chartkick and impressionist gem render not working

Hey Jacob,

So I have added a cached impressions_count counter and column, here is the full schema file

ActiveRecord::Schema.define(version: 20171207012830) do

  # These are extensions that must be enabled in order to support this database
  enable_extension "plpgsql"

  create_table "dashboard_raffles", force: :cascade do |t|
    t.string "title"
    t.string "organisation"
    t.integer "prizes"
    t.float "raise_limit"
    t.datetime "deadline"
    t.integer "max_entires"
    t.float "ticket_price"
    t.integer "raffle_limit"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.integer "impressions_count"
  end

  create_table "impressions", force: :cascade do |t|
    t.string "impressionable_type"
    t.integer "impressionable_id"
    t.integer "user_id"
    t.string "controller_name"
    t.string "action_name"
    t.string "view_name"
    t.string "request_hash"
    t.string "ip_address"
    t.string "session_hash"
    t.text "message"
    t.text "referrer"
    t.text "params"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["controller_name", "action_name", "ip_address"], name: "controlleraction_ip_index"
    t.index ["controller_name", "action_name", "request_hash"], name: "controlleraction_request_index"
    t.index ["controller_name", "action_name", "session_hash"], name: "controlleraction_session_index"
    t.index ["impressionable_type", "impressionable_id", "ip_address"], name: "poly_ip_index"
    t.index ["impressionable_type", "impressionable_id", "params"], name: "poly_params_request_index"
    t.index ["impressionable_type", "impressionable_id", "request_hash"], name: "poly_request_index"
    t.index ["impressionable_type", "impressionable_id", "session_hash"], name: "poly_session_index"
    t.index ["impressionable_type", "message", "impressionable_id"], name: "impressionable_type_message_index"
    t.index ["user_id"], name: "index_impressions_on_user_id"
  end

  create_table "users", force: :cascade do |t|
    t.string "email", default: "", null: false
    t.string "encrypted_password", default: "", null: false
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer "sign_in_count", default: 0, null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.inet "current_sign_in_ip"
    t.inet "last_sign_in_ip"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["email"], name: "index_users_on_email", unique: true
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
  end

end

Here is the migration

class AddImpressionsCountToDashboardRaffle < ActiveRecord::Migration[5.1]
  def change
    add_column :dashboard_raffles, :impressions_count, :int, default: 0
  end
end

The counter goes up on refresh so the counter works.

Here is the raffle.rb model

class Dashboard::Raffle < ApplicationRecord
  is_impressionable :counter_cache => true, :column_name => :impressions_count
end

I still have the same code in the charts_controller.rb so I'm not sure if I need to change anything here now. The impressons are still not showing in the graph.

Posted in Chartkick and impressionist gem render not working

EDIT 1

Here is a screenshot of the current graph

Original Post

I'm using both chartkick and the impressionist gem and I seem to be running into it's not working in regards the current implementation I am trying to show the impressions per day in the graph.

I have a dashboard, with the raffles built in and I'm trying to get the impressions from the raffles to show in a graph on the Dashboard index using an _overview.html.erb partial.

Here is how I have the code so far.

_overview.html.erb

<%= area_chart charts_impressions_path, colors: ["#7123D1"] %>

raffles_controller.rb

class Dashboard::RafflesController < ApplicationController
  before_action :set_dashboard_raffle, only: [:show, :edit, :update, :destroy]

  def show
    @dashboard_raffle = Dashboard::Raffle.find(params[:id])
    impressionist(@dashboard_raffle)
  end

  def new
    @dashboard_raffle = Dashboard::Raffle.new
  end

  def edit
  end

  def create
    @dashboard_raffle = Dashboard::Raffle.new(dashboard_raffle_params)

    if @dashboard_raffle.save
      redirect_to @dashboard_raffle, notice: 'Raffle was successfully created.'
    else
      render :new
    end
  end

  def update
    if @dashboard_raffle.update(dashboard_raffle_params)
      redirect_to @dashboard_raffle, notice: 'Raffle was successfully updated.'
    else
      render :edit
    end
  end

  def destroy
    @dashboard_raffle.destroy
    redirect_to dashboard_raffles_url, notice: 'Raffle was successfully destroyed.'
  end

  private

    def set_dashboard_raffle
      @dashboard_raffle = Dashboard::Raffle.find(params[:id])
    end

    def dashboard_raffle_params
      params.require(:dashboard_raffle).permit(:title, :organisation, :prizes, :raise_limit, :deadline, :max_entires, :ticket_price, :raffle_limit)
    end
end

raffle.rb

class Dashboard::Raffle < ApplicationRecord
  is_impressionable
  belongs_to :user
end

charts_controller.rb

class ChartsController < ApplicationController
  def impressions
    render json: impressions = Dashboard::Raffle.all.map{ |r| r.impressions }.flatten
  end
end

dashboard.rb

module Dashboard
  def self.table_name_prefix
    'dashboard_'
  end
end

dashboard_controller.rb

class DashboardController < ApplicationController
  before_action :authenticate_user!

  def index
    @dashboard_raffles = Dashboard::Raffle.all
  end
end

Here is the

Any help here is appreciated.

Switched back to using form_tag from the simple_form gem, this fixed the issue.