How to add tanker to a simple application
Ruby JavaScript
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
app
config
db
public
script
test
vendor/plugins
.gitignore
Gemfile
README
Rakefile
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.