0
votes

I have already tried to go through solutions like this, but I'm a Rails beginner and just building my first app after going through Pragmatic Studio Rails I & II Course

Basically, I want to build a simple listing site like BookYogaRetreats.com I'm trying to figure out how to implement the filter logic. So far I have a listing model, categories & categorizations.

Listing Model:

has_many :categorizations, dependent: :destroy
has_many :categories, through: :categorizations

has_attached_file :image, styles: { :medium => "200x200#" }
validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/

validates :title, presence: true, uniqueness: true

paginates_per 15

scope :by_category, lambda { |category| includes(:categories).where(:categories => { :name => category }) }

Categorization Model:

belongs_to :listing
belongs_to :category

Categories Model:

has_many :categorizations, dependent: :destroy
has_many :listings, through: :categorizations

My Listings Controller index action looks like this (I've been experimenting a lot...)

class ListingsController < ApplicationController
  before_action :find_listing, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!, except: [:index, :show]
  before_filter :load_data, only: [:index]

def index
  @listings = @listings.includes(:categories).where(categories: { id: @category}) if @category_ids
  @listings = @listings.page(params[:page])

  respond_to do |format|
    format.js
    format.html
  end  
end

And in my jumbotron partial, which includes the filter dropdowns I have the following:

<div class="col-sm-6 col-md-4">
  <%= select_tag("listing[category_id]", options_from_collection_for_select(@categories, "id", "name") , { :prompt => 'Select a Category' }) %>
<%= submit_tag nil, class: "form_submit", method: "get" %>
</div> 

My listings/index.html.erb looks like this:

<% @listings.each_slice(3) do |listings|%>
  <div id="listings">
  <div class="row">
    <% listings.each do |listing|%>
      <div class="col-md-4">
        <div class="listing">
          <div class="image_wrapper">
            <%= link_to listing do %>
              <%= image_tag listing.image.url(:medium) %>
            <% end %> 
            <h2><%= link_to listing.title, listing %></h2>
            <p><%= listing.start_date %> - <%= listing.end_date %></p> 
          </div>   
        </div>    
      </div>
    <% end %>
  </div>
</div>  

I've tried to figure something out for the past two days, been experimenting with Filterific Gem as well as Ransack. I really don't want to use gems and at the moment I don't understand what I need to do. I would be fine with a a category filter, which upon clicking the submit button reloads the page showing all listings that belong to that particular category? Having a has_many through relationship probably doesn't make it easier.

I'd love to be able to have something like listings?by_category=seminars, which then reloads the listings view index.html.erb and only shows the listings that include the category seminars.

I might be completely on the wrong track here. Any pointers would be greatly appreciated.Many thanks.

1
Can anyone help with this?CKP

1 Answers

1
votes

Managed to find a solution here:

My view:

<%= form_tag listings_path, :controller => 'listings', :action => 'index', :method => 'get', :id => "category_select" do %>
  <%= collection_select( nil, :category_id, Category.all, :id, :name, { :include_blank => 'All Categories'} , { :class => 'form-control' })  %>
  <%= submit_tag nil, class: "form_submit" %>
<% end %>

My controller index action:

@listings = Listing.includes(:categorizations).page(params[:page])

if params[:category_id].blank?
  @listings
else
  @category_id = Category.find_by(id: params[:category_id])
  @listings = @category_id.listings
end

respond_to do |format|
  format.js
  format.html
end  

This will then allow me to use /listings?category_id=5 and solves the problem. If you have any more elegant tips, please let me know.