Skip to content

softr8/catalogillo

Repository files navigation

Catalogillo

High performance catalogs page engine for ruby on rails, it uses solr to power all catalog pages and no database is needed, you can index new data using services, add new products, categories and dynamic categories (searches) and this engine will take care of render catalogs with ultra high performance.

Build status

<img src=“https://travis-ci.org/softr8/catalogillo.png” />

Ruby on Rails Engine

Mount this engine in your rails app, customize your layout and index products and launch it to tons of users!

Schema

Product
  id: Product unique identifier
  name: Product Name
  category_ids: Category Ids (Array)
  price: Product Price
  sale_price: Product Sale Price
  on_sale: Product Sale Price active?
  version: Current Product Version, expires cache when changed
  images: Product images (Array)
  high_res_images: Product images (Array)
  fulltext_keywords: Product description to be used in searches
  status: Product Status
  description: Product short description
  long_description: Product long description
  launch_date: Product available date
  pdp_url: Product detail page url

Dynamic Category
  id: Dynamic Category unique identifier
  name: Dynamic Category name
  slug: Dynamic Category slug's name
  search_query: Search Query (Hash)
  sorting_options: Sorting options to display (Hash)
  version: Current Dynamic Category Version, expires cache when changed

Indexing new products

You can send updates to this rails app from your main ecomm app via API, the endpoints are:

POST   /namespace/api/v1/products/index(.:format)
DELETE /namespace/api/v1/products/destroy/:id(.:format)
POST   /namespace/api/v1/dynamic_categories/index(.:format)

Categories

Creating categories with dynamic content(faceted) is as easy as use solr query language, it’s stored in json format then decoded and catalogillo applies the filters to get the desired results. Examples:

{
  category_ids: {between: 1006..1007},
  name: {starting_with: "sale"},
  state: {equal_to: 'active'}
}

{
  price: {greater_than: 50},
  on_sale: {equal_to: true},
  state: {equal_to: 'active'}
}

This filters are going to return all products that the name starts with sale and the category_ids are between those ids, remember that category_ids is a multi-value field and solr filters the correct data out of the box, it’s very easy to assign multiple categories to a single product. More info here in [Sunspot](github.com/sunspot/sunspot/wiki/Scoping-by-attribute-fields) documentation.

Usage

Install this gem into a rails application and do not use active record and mount the engine in your desired namespace

$ rails new supper_app --skip-active-record --skip-test-unit

#Gemfile
gem 'catalogillo', github: '/softr8/catalogillo'

#for better performance, add this too:
gem 'multi_fetch_fragments'

#config/routes.rb
mount Catalogillo::Engine => "/store"

Personalize your application layout and that’s it! You can build some jsonp calls to your main ecomm to show shopping cart status in the header, or hook with unobstrusive javascript to build a quicklook.

For some reason I haven’t had time to look, you need to include in your gemfile kaminari gem.

Config

You can control global configurations

Catalogillo.config do |config|
  config.per_page = 48
  config.page = 1
  config.default_image = "http://cdn.super-domain.com/images/no-image.png"
  config.default_product_tile = {tag: "li", class: ""}
  config.default_products_container = {tag: "lu", class: "unstyled"}

  #How much the cache is valid
  config.cache_expires_in = 5.minutes

  #If you need custom fields in product model, just add them here, example:
  # {name: "my_custom_field", type: "String", required: true, description: "Product field I needed"}
  config.products_extra_fields = []

  #Default filters applied everywhere
  config.default_search_filters = { status: {equal_to: 'active'}, launch_date: {less_than: "FN_TIME_ZONE_NOW" } }

  #Default units on hand scarcity level
  config.default_scarcity_level = 5
end

Implementing searching functionality

Put a piece of code like this one anywhere in your layout or partial to get the search input, it will automatically work

<%= form_tag(catalogillo_search_path, method: :get) do%>
  <%= text_field_tag :keyword %>
  <input type="submit" value="Submit">
<% end %>

Demo

If you want to have a look at it, you can launch the dummy app from spec’s folder

cd spec/dummy
bundle
bundle exec rake sunspot:solr:start
bundle exec rails c
  require './db/seed.rb'
  exit
bundle exec rails s

TODO

  • Add security to API endpoints

  • Even more caching layers

  • Lazy loading Product Images

  • More Functions

  • Run Tests against Rails 4

Benchmarks

I did some preliminary benchmark tests and I got this using my MBP(mid 2012 retina display):

$ unicorn_rails -c config/unicorn.rb -E production -D #starts 8 workers

$ ab -c 8 -n 1000 http://127.0.0.1:8080/store/all
This is ApacheBench, Version 2.3 <$Revision: 655654 $>

Concurrency Level:      8
Time taken for tests:   3.699 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      18506000 bytes
HTML transferred:       17897000 bytes
Requests per second:    270.34 [#/sec] (mean)
Time per request:       29.593 [ms] (mean)
Time per request:       3.699 [ms] (mean, across all concurrent requests)
Transfer rate:          4885.62 [Kbytes/sec] received

It used memcached cache store, solr storing 10k products and 1 category

About the author

I work at MagmaLabs, it is a leading Ruby and Rails consultancy firm based in Mexico currently doing business with startups in the United States. We specialize in building and growing Rails applications, by increasing your IT crew onsite or offsite. We pick our projects carefully, as we only work with companies we believe in.

License

This project uses MIT-LICENSE.

About

High performance products catalog engine, powered by solr

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •