Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

How to add tanker to a simple application

branch: master

Fetching latest commit…

Octocat-spinner-32-eaf2f5

Cannot retrieve the latest commit at this time

Octocat-spinner-32 app
Octocat-spinner-32 config
Octocat-spinner-32 db
Octocat-spinner-32 public
Octocat-spinner-32 script
Octocat-spinner-32 test
Octocat-spinner-32 vendor
Octocat-spinner-32 .gitignore
Octocat-spinner-32 Gemfile
Octocat-spinner-32 README
Octocat-spinner-32 Rakefile
Octocat-spinner-32 config.ru
README
IndexTank-Tanker Tutorial

This is a step-by-step tutorial to add Tanker to every single rails application. 

>> git clone git@github.com:flaptor/rails3-tanker-tutorial.git
>> cd rails3-tanker-tutorial 
>> rake db:migrate
>> rails server

go to http://localhost:3000/posts and add some posts to check that everything is going fine

Add tanker gems to Gemfile:
gem 'tanker'
gem 'json_pure', '1.4.6', :require => 'json'
gem 'will_paginate'


>> echo "Rails3TtDemo::Application.config.index_tank_url = 'PRIVATE API URL'" > config/initializers/tanker.rb

Add simple Tanker configuration to Post class

include Tanker                             # include Tanker's module
tankit 'rails_3_tanker_tutorial' do        # set the name of the index that tanker will use for this class
  indexes :name                            # index the field 'name'
  indexes :title                           # index the field 'title'
  indexes :content                         # index the field 'content'
  indexes :timestamp do                    # index the field 'timestamp' with the creation timestamp
    Time.new.to_i
  end
  indexes :url do                          # index the field 'url' with the value "/posts/" + self.id.to_s
    "/posts/" + self.id.to_s
  end

end
after_save :update_tank_indexes            # add hooks to save, update 
after_destroy :delete_tank_indexes         # and delete methods



>> rake tanker:clear_indexes    # delete and create all indexes defined by tanker
>> rake tanker:reindex          # add all the objects in your database to IndexTank


Add a search form and a controller method to handle it:

- Add this piece of code to apps/views/posts/index.html.erb
<%= form_tag(search_path, :method => "get", :id => "search_form") do %>
  <%= label_tag(:query, "Search for:") %>
  <%= text_field_tag(:query) %>
  <%= submit_tag("Search") %>
<% end %>

- Add this piece of code to apps/controllers/posts_controller.rb
def search
  @posts = Post.search_tank(params[:query])

  respond_to do |format|
    format.html { render :action => 'index' }
    format.xml  { render :xml => @posts }
  end
end

Add realtime scoring functions:

- inside the 'tankit' block in app/models/post.rb, add the following code that declares one document variable and one scoring function

    variables do
      {
        0 => votes.nil? ? 0 : votes
      }
    end

    functions do
      {
        1 => "d[0]"                         # sort desc by votes
      }
    end

- add an action in apps/controllers/posts_controller.rb to update 'votes' variables

  # PUT /posts/:id/vote
  def vote
    post = Post.find(params[:id])
    post.votes = post.votes.nil? ? 1 : post.votes + 1
    post.save

    @posts = Post.all

    respond_to do |format|
      format.html { render :action => 'index' }
      format.xml  { render :xml => @posts }
    end
  end

- add a route declaration in config/routes.rb
  match '/posts/:id/vote' => 'posts#vote'


- add a link in app/views/posts/index.html.erb to update 'votes' variable and 
  a label to show current votes of each method

<%= link_to 'Vote up', :controller => "posts", :action => "vote", :id => post.id %>

<h4>by <%= post.name %> (<%= post.votes.nil? ? 0 : post.votes %>)</h4>

- In search action in apps/controllers/posts_controller.rb add a function option to tanker call

@posts = Post.search_tank(params[:query], :function => 1)

- finally, run a rake task to create functions in indextank

>> rake tanker:functions

Now search should show posts sorted by their votes.

** You can also filter documents by functions. function 2 will be "age".
   let's give the users the option to filter by that functions. remember that recently added documents age is 0.

- in app/models/post.rb add the function '2 => "age"' in the function declaration:
    functions do
      {
        1 => "d[0]",                         # sort desc by votes
        2 => "age"                           # sort desc by votes
      }
    end

- change the search action in apps/controllers/posts_controller.rb to handle new parameters

  def search
    query = params[:query].nil? ? "" : params[:query] + '*'

    from_unit = params[:from_unit].nil? ? 1 : params[:from_unit].to_i
    from = params[:from].nil? || params[:from] == ""? "*" : params[:from].to_i * from_unit
    to_unit = params[:to_unit].nil? ? 1 : params[:to_unit].to_i
    to = params[:to].nil? || params[:to] == "" ? "*" : params[:to].to_i * to_unit

    if from != "*" or to != "*"
      @posts = Post.search_tank(query, :function => 1, 
        :filter_functions => {2 => [[from, to]]})
    else 
      @posts = Post.search_tank(query, :function => 1)
    end

    respond_to do |format|
      format.html { render :action => 'index' }
      format.xml  { render :xml => @posts }
    end
  end

- add some inputs inside the search form in app/views/posts/index.html.erb

  <div id="adv_search">
  <%= label_tag(:from, "Age from:") %>
  <%= text_field_tag(:from, nil, :style => 'width:50px;') %>
  <select id="from_unit" name="from_unit">
    <option value="86400">Days</option>
    <option value="3600">Hour</option>
    <option value="60">Min</option>
    <option value="1">Sec</option>
  </select>
  <%= label_tag(:to, "to:") %>
  <%= text_field_tag(:to, nil, :style => 'width:50px;') %>
  <select id="to_unit" name="to_unit">
    <option value="86400">Days</option>
    <option value="3600">Hour</option>
    <option value="60">Min</option>
    <option value="1">Sec</option>
  </select>
  </div>


Now you could filter your post by age.

Something went wrong with that request. Please try again.