Impressionist most_viewed items not working

155 Views Asked by At

I've been unable to retrieve most viewed posts in my app with impressionist gem. Everything works fine with normal page views. I've tried this on another app and it works well. The only difference between the two apps is that the one that that worked uses SQLITE while the other PG.

I've implemented it by installing the gem, i generated the table migration rails g impressionist and added the impressions_count to posts

rails g migration add_impressions_count_to_posts impressions_count:integer

Added this to Post.rb

is_impressionable :counter_cache => true

and

Post.order('impressions_count DESC')

Added this to posts_controller.rb in show action

@most_viewed = Post.order('impressions_count DESC').take(20)

Below is my post controller code:

class PostsController < ApplicationController
  before_action :redirect_if_not_signed_in, only: [:new, :edit, :destroy, :interests_feed]
  before_action :find_post, only: [:show, :edit, :update, :destroy]
  before_action :find_category
  before_action :find_contacts
  before_action :set_actions
  impressionist :actions=>[:show,:index]

  def show
    if user_signed_in?
      @message_has_been_sent = conversation_exist?
    end
    impressionist(@post)
    @most_viewed = Post.order('impressions_count DESC').take(10)
  end

  def new
    @branch = params[:branch]
    @categories = Category.where(branch: @branch)
    @post = Post.new
  end

  def create
    @post = Post.new(post_params)
    if @post.save 
      redirect_to post_path(@post) 
    else
      redirect_to root_path
    end
  end

  def edit
    @categories = Category.all.map{ |c| [c.name, c.id] }
  end

  def update
    if @post.update(post_params)
      redirect_to post_path(@post)
    else
      render 'edit'
    end
  end

  # DELETE /stories/1
  # DELETE /stories/1.json
  def destroy
    @post.destroy
    respond_to do |format|
      format.html { redirect_to root_path, notice: 'post was successfully deleted.' }
      format.json { head :no_content }
    end
  end

  def hobby
    impressionist(@post)
    posts_for_branch(params[:action])
  end

  def study
    posts_for_branch(params[:action])
  end

  def team
    posts_for_branch(params[:action])
  end

  def interests_feed
    @my_interests = current_user.tag_ids
    @posts = Post.select { |p| (p.tag_ids & @my_interests).any? }
  end

  def most_viewed
    @most_viewed = Post.order('impressions_count DESC').take(20)
    @categories = Category.where(branch: @branch)
  end

  def saved_questions
    @saved_questions = current_user.saved_questions
  end

  private

  def conversation_exist?
    Private::Conversation.between_users(current_user.id, @post.user.id).present?
  end

  def post_params
    params.require(:post).permit(:content, :title, :category_id, :tag_list, tag_ids: [])
                         .merge(user_id: current_user.id)
  end

  def find_post
    @post = Post.includes(:tags).find(params[:id])
  end

  def find_category
    @categories = Category.where(branch: @branch)
  end

  def find_contacts
    @contacts = user_signed_in? ? current_user.all_active_contacts : ''
  end

  def posts_for_branch(branch)
    @categories = Category.where(branch: branch)
    @posts = get_posts.paginate(page: params[:page])
    @most_viewed = Post.order('impressions_count DESC').take(20)
    respond_to do |format|
      format.html
      format.js { render partial: 'posts/posts_pagination_page' }
    end
  end

  def get_posts
    PostsForBranchService.new({
      search: params[:search],
      category: params[:category],
      branch: params[:action]
    }).call
  end

  def set_actions
    if user_signed_in?
      @saved_questions = current_user.saved_questions
    end
  end

end

and my post model

class Post < ApplicationRecord
  belongs_to :user
  belongs_to :category

  is_impressionable :counter_cache => true

  Post.order('impressions_count DESC')

  validates :title, presence: true, length: { minimum: 5, maximum: 255 }
  validates :content, presence: true, length: { minimum: 20, maximum: 1000 }
  validates :category_id, presence: true

  default_scope -> { includes(:user).order(created_at: :desc) }

  scope :by_category, -> (branch, category_name) do 
    joins(:category).where(categories: {name: category_name, branch: branch}) 
  end

  scope :by_branch, -> (branch) do
    joins(:category).where(categories: {branch: branch}) 
  end

  scope :search, -> (search) do
    where("title ILIKE lower(?) OR content ILIKE lower(?)", "%#{search}%", "%#{search}%")
  end

  scope :most_recent, -> { order(created_at: :desc) }

  has_many :taggings
  has_many :tags, through: :taggings
  has_many :comments, as: :commentable, dependent: :destroy
  has_many :upvotes, dependent: :destroy
  has_many :save_questions, dependent: :destroy

  def tag_list
    self.tags.collect do |tag|
      tag.name
    end.join(", ")
  end

  def tag_list=(tags_string)
    tag_names = tags_string.split(",").collect{|s| s.strip.downcase}.uniq
    new_or_found_tags = tag_names.collect { |name| Tag.friendly.find_or_create_by(name: name) }
    self.tags = new_or_found_tags
  end

  def related_posts
      Post.joins(:tags).where(tags: { id: self.tags.pluck(:id) }).where.not(id: self.id)
  end

end

show.html.erb

<div id="single-post-content" class="container">
  <div class="row">
    <div class="col-sm-8 bg-white">
      <h1><%= @post.title %></h1>
      <hr class="custom-hr">
      <% unless @post.tags.blank? %>
        <p>
          <span>
              Tags:
              <% @post.tags.each do |tag| %>
                <%= link_to tag.name, tag_path(tag), class: "button button_highlight" %>
              <% end %>
          </span>
          </p>
      <% end %>

      <p>
        <span class="text-muted">Asked on <%= @post.created_at.strftime('%-d %B %Y')%> ago by <%= link_to @post.user.name, profile_path(@post.user.name) %> <%= link_to (image_tag @post.user.avatar.url(:comment), class: "img-circle"), profile_path(@post.user.name) %></span> | <span class="text-muted"><%= pluralize(@post.comments.count, "Responses") %></span> | <span class="text-muted"><%= pluralize(@post.impressionist_count, "View") %></span>

        <span id="post_<%= @post.id %>_save_questions">
          <%= render partial: "save_questions", locals: {post: @post} %>
        </span>

      </p>

      <p id="post_<%= @post.id %>_upvotes">
        <%= render partial: "upvotes", locals: {post: @post} %>
      </p>

      <hr class="custom-hr">

      <p><%= sanitize @post.content %></p>

      <% if user_signed_in? %>
        <% if @post.user_id == current_user.id %>
          <span><%= link_to 'Edit Question', edit_post_path(@post), class: "btn btn-warning btn-sm" %></span>
          <span><%= link_to 'Delete Question', @post, method: :delete, data: { confirm: 'Are you sure?' }, class: "btn btn-danger btn-sm" %></span>
        <% end %>
      <% end %>

      <hr class="custom-hr">

      <div>
        <p><b>Note:</b> This user doesn't know if you're sending this D.M as a response to a question. so your DM could be in this format <i>"As a response to "Are you a male?", Yes, I am.</i></p>

        <%= link_to 'Send your response as a private message', open_private_conversation_path(id: @post.user.id), remote: true, method: :post, class: 'bigger-screen-link btn btn-primary btn-sm' %>

        <%= link_to 'Send your response as a private message', open_messenger_path(id: @post.user.id, smaller_device: true, type: 'private'), class: 'smaller-screen-link btn btn-primary btn-sm' %>
      </div>

      <p>Or write a public response below.</p>

      <br>
      <div>
        <%= render "comments/widget", commentable: @post %>
      </div>
    </div>

    <div class="col-sm-4">
      <h4>Quick Navigation</h4>

      <div class="list-group">
        <%= link_to 'My Interests', my_interests_path, class: "list-group-item" %>
        <%= link_to 'Trending', trending_path, class: "list-group-item" %>
        <a href="#" class="list-group-item">Hot</a>
        <%= link_to '20 Most Viewed', most_viewed_path, class: "list-group-item" %>
        <a href="#" class="list-group-item">Unanswered</a>
        <a href="#" class="list-group-item">From Friends</a>
      </div>

      <h4>Related Questions</h4>
      <hr class="custom-hr">
      <% unless @post.related_posts.blank? %>
        <ol>
          <% @post.related_posts.most_recent.limit(10).reject { |p| p.id == @post.id }.each do |post| %>
            <li><%= link_to post.title, post_path(post.id) %></li>
          <% end %>
        </ol>
      <% else %>
        <p class="text-warning">This question is not related to others.</p>
      <% end %>

      <br>

      <div class="">
        <h4>20 Most Viewed in this Directory.</h4>
        <ol>
          <% @most_viewed.each do |post| %>
            <li><%= link_to post.title, post_path(post.id) %> (<%= post.impressionist_count %> Views) </li>
          <% end %>
        </ol>
      </div>

      <br>

      <% unless @post.category.blank? %>

        <h4>More in Questions <%= link_to @post.category.name, posts_path(branch: @post.category.name) %></h4>
        <hr class="custom-hr">
        <ol>
          <% @post.category.posts.most_recent.limit(11).reject { |p| p.id == @post.id }.each do |post| %>
            <li><%= link_to post.title, post_path(post.id) %></li>
          <% end %>
        </ol>
      <% end %>

    </div>
  </div><!-- row -->
</div>

I have the imprssions table in my schema

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
0

There are 0 best solutions below