session_logger 0.0.1 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. data/README.rdoc +94 -1
  2. data/Rakefile +0 -2
  3. data/lib/generators/session_logger/initializer_generator.rb +12 -0
  4. data/lib/generators/session_logger/templates/session_logger.rb +15 -0
  5. data/lib/session_logger/session_logging.rb +70 -0
  6. data/lib/session_logger/version.rb +1 -1
  7. data/lib/session_logger.rb +28 -1
  8. data/test/dummy/app/assets/javascripts/users.js +2 -0
  9. data/test/dummy/app/assets/stylesheets/scaffold.css +56 -0
  10. data/test/dummy/app/assets/stylesheets/users.css +4 -0
  11. data/test/dummy/app/controllers/application_controller.rb +1 -0
  12. data/test/dummy/app/controllers/users_controller.rb +83 -0
  13. data/test/dummy/app/helpers/users_helper.rb +2 -0
  14. data/test/dummy/app/models/user.rb +2 -0
  15. data/test/dummy/app/views/users/_form.html.erb +29 -0
  16. data/test/dummy/app/views/users/edit.html.erb +6 -0
  17. data/test/dummy/app/views/users/index.html.erb +27 -0
  18. data/test/dummy/app/views/users/new.html.erb +5 -0
  19. data/test/dummy/app/views/users/show.html.erb +20 -0
  20. data/test/dummy/config/database_example.yml +25 -0
  21. data/test/dummy/config/initializers/secret_token.rb +1 -1
  22. data/test/dummy/config/initializers/session_logger.rb +17 -0
  23. data/test/dummy/config/routes.rb +58 -2
  24. data/test/dummy/db/development.sqlite3 +0 -0
  25. data/test/dummy/db/migrate/20111104001311_create_users.rb +11 -0
  26. data/test/dummy/db/migrate/20111105072946_add_sl_campaign_to_user.rb +5 -0
  27. data/test/dummy/db/schema.rb +25 -0
  28. data/test/dummy/db/test.sqlite3 +0 -0
  29. data/test/dummy/log/development.log +7769 -0
  30. data/test/dummy/log/test.log +1919 -0
  31. data/test/dummy/test/fixtures/users.yml +11 -0
  32. data/test/dummy/test/functional/application_controller_test.rb +13 -0
  33. data/test/dummy/test/functional/users_controller_test.rb +92 -0
  34. data/test/dummy/test/unit/helpers/users_helper_test.rb +4 -0
  35. data/test/{integration/navigation_test.rb → dummy/test/unit/user_test.rb} +1 -4
  36. data/test/dummy/tmp/cache/assets/C70/E50/sprockets%2F076e5295d303281065f2740dfa09c02a +0 -0
  37. data/test/dummy/tmp/cache/assets/CAA/620/sprockets%2F87b209c0c9da28094a8d5581a21262c6 +0 -0
  38. data/test/dummy/tmp/cache/assets/CDC/BB0/sprockets%2Fff6ad535237265e32f00941ea62ec807 +0 -0
  39. data/test/dummy/tmp/cache/assets/CDF/070/sprockets%2F70e3c8a3916622c17858d520dcee0d92 +0 -0
  40. data/test/dummy/tmp/cache/assets/CF0/1D0/sprockets%2F6fc757c2c8329244ca95d6909865bbc2 +0 -0
  41. data/test/dummy/tmp/cache/assets/D0E/FD0/sprockets%2Feda9627533d843bb16038063e48c1fbf +0 -0
  42. data/test/dummy/tmp/cache/assets/D11/D20/sprockets%2Fcac21eac42152981882bf9e489316af4 +0 -0
  43. data/test/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
  44. data/test/dummy/tmp/cache/assets/D46/650/sprockets%2Ff56253b5f374fff1a33fbbc9881c9124 +0 -0
  45. data/test/dummy/tmp/cache/assets/D54/ED0/sprockets%2F71c9fa01091d432b131da3bb73faf3d4 +0 -0
  46. data/test/dummy/tmp/cache/assets/D73/220/sprockets%2F3dbc0a37f98fb43ec819b85a64d32c55 +0 -0
  47. data/test/dummy/tmp/cache/assets/D84/210/sprockets%2Fabd0103ccec2b428ac62c94e4c40b384 +0 -0
  48. data/test/dummy/tmp/cache/assets/DF8/7B0/sprockets%2Fb5580c4b03db7c38cfd55ab7a8f3aad8 +0 -0
  49. data/test/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  50. data/test/session_logger_test.rb +30 -0
  51. data/test/test_helper.rb +29 -6
  52. data/test/tmp/config/initializers/session_logger.rb +15 -0
  53. data/test/unit/intitializer_generator_test.rb +15 -0
  54. data/test/unit/session_logging_test.rb +13 -0
  55. metadata +185 -12
  56. data/app/assets/javascripts/session_logger/application.js +0 -9
  57. data/app/assets/stylesheets/session_logger/application.css +0 -7
  58. data/app/controllers/session_logger/application_controller.rb +0 -4
  59. data/app/helpers/session_logger/application_helper.rb +0 -4
  60. data/app/views/layouts/session_logger/application.html.erb +0 -14
  61. data/config/routes.rb +0 -2
  62. data/lib/session_logger/engine.rb +0 -5
data/README.rdoc CHANGED
@@ -1,3 +1,96 @@
1
1
  = SessionLogger
2
2
 
3
- This project rocks and uses MIT-LICENSE.
3
+ The session logger is simply a observer that automatically writes data from
4
+ the session to models with matching columns.
5
+
6
+
7
+ == What it is good for
8
+
9
+ Session Logger is great for recording session based activites you want to
10
+ group together.
11
+
12
+ Questions session logger can help answer:
13
+
14
+ * How many users came in from a given ad campaign?
15
+
16
+ * How many invites did those users from that campaign send?
17
+
18
+ * How many purchases came when we directed people to this landing page?
19
+
20
+ * Pretty much anything about users activity over a single session...
21
+
22
+ == Setup
23
+
24
+ First install the gem:
25
+ gem install session_logger
26
+
27
+ And/or add it to your Gemfile
28
+ gem session_logger
29
+
30
+ Then create the initializer:
31
+ rails generate session_logger:initializer
32
+
33
+ As a performance optimization you can add the list of models to observe in the initializer:
34
+ config.session_logger.logged_models = [MODEL_CONSTANTS,...]
35
+
36
+ Finally add 'enable_session_logger' to Application controller (or any controller you want logging to occur)
37
+ ApplicationController < ActionController::Base
38
+ enable_session_logger
39
+ end
40
+
41
+
42
+ == Usage
43
+
44
+ 1. Create metadata columns on the models you want metadata recorded on
45
+ 2. Be sure to prefix metadata columns with the model prefix ("sl_" by default)
46
+ 3. Simply set that same prefixed name in the session and that metadata will be stored anytime a observed record is created during that session.
47
+
48
+
49
+ == How it works
50
+
51
+ We create a new observer type that has access to both the controller and the
52
+ model level call backs that will write metadata found in the session to models
53
+ at creation time.
54
+
55
+ When a session key is found that matches a prefixed column for the model that
56
+ is being created we simply append that data before save to the model effectively
57
+ appending the metadata for that users session.
58
+
59
+ == Gotchas
60
+
61
+ If you start monitoring a ton of metadata around the user you have to switch
62
+ to db sessions instead of cookie store.
63
+
64
+ Don't clear your whole session haphazardly. Thats where the metadata is stored
65
+
66
+
67
+ == Choice to use columns instead of polymorphic table
68
+
69
+ One of the primary conerns we had when we were developing this gem was the
70
+ trade offs between adding additional namespaced columns on the records
71
+ and creating a seperate polymorphic join table for the logging information.
72
+
73
+ At the end of the day we choose to implement the logging solution with
74
+ namespaced columns. Here are the pros and cons.
75
+
76
+ Columns solution:
77
+
78
+ Pros:
79
+ * Speed and simplicity in creation of reports.
80
+ * Speed of writes of those rows. (one write call vs two)
81
+ * Customization of metadata per model without Null columns
82
+
83
+ Cons:
84
+ * Pain to add so many repeated columns to potentially many tables
85
+ * (OK) Slow down in read of individual rows (can be mitigated with scoped select statements)
86
+ * (OK) Metadata doesn't have its own timestamp (not really applicable as it should be the same as the write time of the original record)
87
+
88
+
89
+ The only real con that we couldn't work around is the initial number of columns
90
+ you will need to add to all your models. Many of them repeat in practice and
91
+ this will give you a bad taste in your mouth but it seems like a better
92
+ solution overall.
93
+
94
+
95
+ == License
96
+ This project rocks and uses MIT-LICENSE.
data/Rakefile CHANGED
@@ -20,8 +20,6 @@ RDoc::Task.new(:rdoc) do |rdoc|
20
20
  rdoc.rdoc_files.include('lib/**/*.rb')
21
21
  end
22
22
 
23
- APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
24
- load 'rails/tasks/engine.rake'
25
23
 
26
24
 
27
25
  Bundler::GemHelper.install_tasks
@@ -0,0 +1,12 @@
1
+ module SessionLogger
2
+ class InitializerGenerator < Rails::Generators::Base
3
+ source_root File.expand_path("../templates", __FILE__)
4
+
5
+ desc "Generator creates a sample initializer for the session_logger"
6
+
7
+ def create_config_files
8
+ copy_file "session_logger.rb", "config/initializers/session_logger.rb"
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ # The configure step must be run after the rails app has finished initializing
2
+ # for the models to respond to observer registration requests
3
+ Rails.application.config.after_initialize do
4
+ SessionLogger.configure do |config|
5
+
6
+ # Default is to observe all models in the models dir
7
+ config.logged_models = Dir["#{Rails.root}/app/models/**/*.rb"].map { |f| File.basename(f, '.*').camelize.constantize }
8
+
9
+ # Performance optimization for only observing certain models
10
+ # config.logged_models = [User]
11
+
12
+ # Customizable model prefixing
13
+ # config.model_prefix = "sl_"
14
+ end
15
+ end
@@ -0,0 +1,70 @@
1
+ module SessionLogger
2
+
3
+ module SessionLogging
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods #:nodoc:
7
+
8
+ # Options are the same as the ones for around filter. See docs for around filter
9
+ def enable_session_logging(options={})
10
+
11
+ raise "Session Logging can't occur without specifying logged_models in initializers" if SessionLogger.logged_models.blank?
12
+
13
+ SessionLogger::SessionObserver.observe(SessionLogger.logged_models)
14
+
15
+ if !ActiveRecord::Base.observers.include? SessionLogger::SessionObserver
16
+ ActiveRecord::Base.observers << SessionLogger::SessionObserver if defined?(ActiveRecord) and defined?(ActiveRecord::Base)
17
+ end
18
+
19
+ sweeper_instance = SessionLogger::SessionObserver.instance
20
+
21
+ around_filter(sweeper_instance, options)
22
+ end
23
+ end
24
+ end
25
+
26
+
27
+ class SessionObserver < ActiveRecord::Observer
28
+ attr_accessor :controller
29
+
30
+ #Required to prevent the observer from un-cleverly looking for Session...
31
+ def self.observed_class
32
+ nil
33
+ end
34
+
35
+ # ------------------------------------------- Legacy around filter calls
36
+ def before(controller)
37
+ self.controller = controller
38
+ true # before method from SessionObserver should always return true
39
+ end
40
+
41
+ def after(controller)
42
+ self.controller = controller
43
+ # Clean up, so that the controller can be collected after this request
44
+ self.controller = nil
45
+ end
46
+
47
+ # ------------------------------------------- ActiveRecord callbacks
48
+ def before_create(record)
49
+ return if controller.blank? || controller.session.blank?
50
+
51
+ candidate_columns = record.attributes.select { |attr| attr.starts_with? SessionLogger.model_prefix }
52
+ candidate_columns.keys.each do |column|
53
+ column = column.to_s
54
+ #Only setting if present prevents empty strings from overriding defaults in the schema
55
+ set_if_present(record, column, controller.session[column])
56
+ end
57
+ #pp controller.session["sl_campaign"]
58
+ #pp record
59
+ end
60
+
61
+ private
62
+ def set_if_present(obj, key, val)
63
+ pp obj
64
+ pp key
65
+ pp val
66
+ obj.send("#{key}=", val) if val.present?
67
+ end
68
+ end
69
+
70
+ end
@@ -1,3 +1,3 @@
1
1
  module SessionLogger
2
- VERSION = "0.0.1"
2
+ VERSION = "1.0.1"
3
3
  end
@@ -1,4 +1,31 @@
1
- require "session_logger/engine"
1
+ require "session_logger/session_logging"
2
2
 
3
3
  module SessionLogger
4
+
5
+ # --------------------------------------------- Rails injection
6
+ # This injects the session logging class methods into the action_controller
7
+ ActiveSupport.on_load(:action_controller) do
8
+ include SessionLogger::SessionLogging
9
+ end
10
+
11
+ # --------------------------------------------- Configuration
12
+ # Defines the session_logger configuration keys for usage in application.rb
13
+ SessionLoggerConfig = Struct.new(:logged_models, :model_prefix)
14
+ @@config = SessionLoggerConfig.new
15
+
16
+ #Allows the initializer to set the configuration for session_logger
17
+ def self.configure(&block)
18
+ block.call(@@config)
19
+ end
20
+
21
+ def self.logged_models
22
+ #Returns a list of models (dependant on rails conventions in the models dir)
23
+ @@config.logged_models
24
+ end
25
+
26
+ def self.model_prefix
27
+ @@config.model_prefix ||= "sl_"
28
+ end
29
+
4
30
  end
31
+
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,56 @@
1
+ body { background-color: #fff; color: #333; }
2
+
3
+ body, p, ol, ul, td {
4
+ font-family: verdana, arial, helvetica, sans-serif;
5
+ font-size: 13px;
6
+ line-height: 18px;
7
+ }
8
+
9
+ pre {
10
+ background-color: #eee;
11
+ padding: 10px;
12
+ font-size: 11px;
13
+ }
14
+
15
+ a { color: #000; }
16
+ a:visited { color: #666; }
17
+ a:hover { color: #fff; background-color:#000; }
18
+
19
+ div.field, div.actions {
20
+ margin-bottom: 10px;
21
+ }
22
+
23
+ #notice {
24
+ color: green;
25
+ }
26
+
27
+ .field_with_errors {
28
+ padding: 2px;
29
+ background-color: red;
30
+ display: table;
31
+ }
32
+
33
+ #error_explanation {
34
+ width: 450px;
35
+ border: 2px solid red;
36
+ padding: 7px;
37
+ padding-bottom: 0;
38
+ margin-bottom: 20px;
39
+ background-color: #f0f0f0;
40
+ }
41
+
42
+ #error_explanation h2 {
43
+ text-align: left;
44
+ font-weight: bold;
45
+ padding: 5px 5px 5px 15px;
46
+ font-size: 12px;
47
+ margin: -7px;
48
+ margin-bottom: 0px;
49
+ background-color: #c00;
50
+ color: #fff;
51
+ }
52
+
53
+ #error_explanation ul li {
54
+ font-size: 12px;
55
+ list-style: square;
56
+ }
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -1,3 +1,4 @@
1
1
  class ApplicationController < ActionController::Base
2
2
  protect_from_forgery
3
+ enable_session_logging
3
4
  end
@@ -0,0 +1,83 @@
1
+ class UsersController < ApplicationController
2
+ # GET /users
3
+ # GET /users.json
4
+ def index
5
+ @users = User.all
6
+
7
+ respond_to do |format|
8
+ format.html # index.html.erb
9
+ format.json { render json: @users }
10
+ end
11
+ end
12
+
13
+ # GET /users/1
14
+ # GET /users/1.json
15
+ def show
16
+ @user = User.find(params[:id])
17
+
18
+ respond_to do |format|
19
+ format.html # show.html.erb
20
+ format.json { render json: @user }
21
+ end
22
+ end
23
+
24
+ # GET /users/new
25
+ # GET /users/new.json
26
+ def new
27
+ @user = User.new
28
+
29
+ respond_to do |format|
30
+ format.html # new.html.erb
31
+ format.json { render json: @user }
32
+ end
33
+ end
34
+
35
+ # GET /users/1/edit
36
+ def edit
37
+ @user = User.find(params[:id])
38
+ end
39
+
40
+ # POST /users
41
+ # POST /users.json
42
+ def create
43
+ @user = User.new(params[:user])
44
+
45
+ respond_to do |format|
46
+ if @user.save
47
+ format.html { redirect_to @user, notice: 'User was successfully created.' }
48
+ format.json { render json: @user, status: :created, location: @user }
49
+ else
50
+ format.html { render action: "new" }
51
+ format.json { render json: @user.errors, status: :unprocessable_entity }
52
+ end
53
+ end
54
+ end
55
+
56
+ # PUT /users/1
57
+ # PUT /users/1.json
58
+ def update
59
+ @user = User.find(params[:id])
60
+
61
+ respond_to do |format|
62
+ if @user.update_attributes(params[:user])
63
+ format.html { redirect_to @user, notice: 'User was successfully updated.' }
64
+ format.json { head :ok }
65
+ else
66
+ format.html { render action: "edit" }
67
+ format.json { render json: @user.errors, status: :unprocessable_entity }
68
+ end
69
+ end
70
+ end
71
+
72
+ # DELETE /users/1
73
+ # DELETE /users/1.json
74
+ def destroy
75
+ @user = User.find(params[:id])
76
+ @user.destroy
77
+
78
+ respond_to do |format|
79
+ format.html { redirect_to users_url }
80
+ format.json { head :ok }
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,2 @@
1
+ module UsersHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ class User < ActiveRecord::Base
2
+ end
@@ -0,0 +1,29 @@
1
+ <%= form_for(@user) do |f| %>
2
+ <% if @user.errors.any? %>
3
+ <div id="error_explanation">
4
+ <h2><%= pluralize(@user.errors.count, "error") %> prohibited this user from being saved:</h2>
5
+
6
+ <ul>
7
+ <% @user.errors.full_messages.each do |msg| %>
8
+ <li><%= msg %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <div class="field">
15
+ <%= f.label :name %><br />
16
+ <%= f.text_field :name %>
17
+ </div>
18
+ <div class="field">
19
+ <%= f.label :password %><br />
20
+ <%= f.text_field :password %>
21
+ </div>
22
+ <div class="field">
23
+ <%= f.label :email %><br />
24
+ <%= f.text_field :email %>
25
+ </div>
26
+ <div class="actions">
27
+ <%= f.submit %>
28
+ </div>
29
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <h1>Editing user</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Show', @user %> |
6
+ <%= link_to 'Back', users_path %>
@@ -0,0 +1,27 @@
1
+ <h1>Listing users</h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <th>Name</th>
6
+ <th>Password</th>
7
+ <th>Email</th>
8
+ <th></th>
9
+ <th></th>
10
+ <th></th>
11
+ </tr>
12
+
13
+ <% @users.each do |user| %>
14
+ <tr>
15
+ <td><%= user.name %></td>
16
+ <td><%= user.password %></td>
17
+ <td><%= user.email %></td>
18
+ <td><%= link_to 'Show', user %></td>
19
+ <td><%= link_to 'Edit', edit_user_path(user) %></td>
20
+ <td><%= link_to 'Destroy', user, confirm: 'Are you sure?', method: :delete %></td>
21
+ </tr>
22
+ <% end %>
23
+ </table>
24
+
25
+ <br />
26
+
27
+ <%= link_to 'New User', new_user_path %>
@@ -0,0 +1,5 @@
1
+ <h1>New user</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Back', users_path %>
@@ -0,0 +1,20 @@
1
+ <p id="notice"><%= notice %></p>
2
+
3
+ <p>
4
+ <b>Name:</b>
5
+ <%= @user.name %>
6
+ </p>
7
+
8
+ <p>
9
+ <b>Password:</b>
10
+ <%= @user.password %>
11
+ </p>
12
+
13
+ <p>
14
+ <b>Email:</b>
15
+ <%= @user.email %>
16
+ </p>
17
+
18
+
19
+ <%= link_to 'Edit', edit_user_path(@user) %> |
20
+ <%= link_to 'Back', users_path %>
@@ -0,0 +1,25 @@
1
+ # SQLite version 3.x
2
+ # gem install sqlite3
3
+ #
4
+ # Ensure the SQLite 3 gem is defined in your Gemfile
5
+ # gem 'sqlite3'
6
+ development:
7
+ adapter: sqlite3
8
+ database: db/development.sqlite3
9
+ pool: 5
10
+ timeout: 5000
11
+
12
+ # Warning: The database defined as "test" will be erased and
13
+ # re-generated from your development database when you run "rake".
14
+ # Do not set this db to the same as development or production.
15
+ test:
16
+ adapter: sqlite3
17
+ database: db/test.sqlite3
18
+ pool: 5
19
+ timeout: 5000
20
+
21
+ production:
22
+ adapter: sqlite3
23
+ database: db/production.sqlite3
24
+ pool: 5
25
+ timeout: 5000
@@ -4,4 +4,4 @@
4
4
  # If you change this key, all old signed cookies will become invalid!
5
5
  # Make sure the secret is at least 30 characters and all random,
6
6
  # no regular words or you'll be exposed to dictionary attacks.
7
- Dummy::Application.config.secret_token = 'd4225e808462cc2cc06cdc92a45ba129fcd1030eb0a28521f3e96c4bdc3633646db81939d7b548cce87965a3e453e910cb6a54bec92a3820c220e9b18b3698de'
7
+ Dummy::Application.config.secret_token = 'ad4026366010c90ed5b554f3c9fd6b6c23377f5f071842f365fb583ed657fe0d827b49b8b07ef6441d0723333c6190ac06ce869298a8fae47ef5fa0b42485933'
@@ -0,0 +1,17 @@
1
+ # The configure step must be run right before the after_initialize callback
2
+ # This allows both tests (which don't wait for after_initialize) and the app
3
+ # to get the appropriate models after they have been initialized. The to_prepare
4
+ # call is the prefect callback for preparing plugins
5
+ Rails.application.config.to_prepare do
6
+ SessionLogger.configure do |config|
7
+
8
+ # Default is to observe all models in the models dir
9
+ config.logged_models = Dir["#{Rails.root}/app/models/**/*.rb"].map { |f| File.basename(f, '.*').camelize.constantize }
10
+
11
+ # Performance optimization for only observing certain models
12
+ # config.logged_models = [User]
13
+
14
+ # Customizable model prefixing
15
+ # config.model_prefix = "sl_"
16
+ end
17
+ end
@@ -1,4 +1,60 @@
1
- Rails.application.routes.draw do
1
+ Dummy::Application.routes.draw do
2
+ resources :users
2
3
 
3
- mount SessionLogger::Engine => "/session_logger"
4
+ # The priority is based upon order of creation:
5
+ # first created -> highest priority.
6
+
7
+ # Sample of regular route:
8
+ # match 'products/:id' => 'catalog#view'
9
+ # Keep in mind you can assign values other than :controller and :action
10
+
11
+ # Sample of named route:
12
+ # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
13
+ # This route can be invoked with purchase_url(:id => product.id)
14
+
15
+ # Sample resource route (maps HTTP verbs to controller actions automatically):
16
+ # resources :products
17
+
18
+ # Sample resource route with options:
19
+ # resources :products do
20
+ # member do
21
+ # get 'short'
22
+ # post 'toggle'
23
+ # end
24
+ #
25
+ # collection do
26
+ # get 'sold'
27
+ # end
28
+ # end
29
+
30
+ # Sample resource route with sub-resources:
31
+ # resources :products do
32
+ # resources :comments, :sales
33
+ # resource :seller
34
+ # end
35
+
36
+ # Sample resource route with more complex sub-resources
37
+ # resources :products do
38
+ # resources :comments
39
+ # resources :sales do
40
+ # get 'recent', :on => :collection
41
+ # end
42
+ # end
43
+
44
+ # Sample resource route within a namespace:
45
+ # namespace :admin do
46
+ # # Directs /admin/products/* to Admin::ProductsController
47
+ # # (app/controllers/admin/products_controller.rb)
48
+ # resources :products
49
+ # end
50
+
51
+ # You can have the root of your site routed with "root"
52
+ # just remember to delete public/index.html.
53
+ # root :to => 'welcome#index'
54
+
55
+ # See how all your routes lay out with "rake routes"
56
+
57
+ # This is a legacy wild controller route that's not recommended for RESTful applications.
58
+ # Note: This route will make all actions in every controller accessible via GET requests.
59
+ # match ':controller(/:action(/:id(.:format)))'
4
60
  end
Binary file
@@ -0,0 +1,11 @@
1
+ class CreateUsers < ActiveRecord::Migration
2
+ def change
3
+ create_table :users do |t|
4
+ t.string :name
5
+ t.string :password
6
+ t.string :email
7
+
8
+ t.timestamps
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ class AddSlCampaignToUser < ActiveRecord::Migration
2
+ def change
3
+ add_column :users, :sl_campaign, :string
4
+ end
5
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: UTF-8
2
+ # This file is auto-generated from the current state of the database. Instead
3
+ # of editing this file, please use the migrations feature of Active Record to
4
+ # incrementally modify your database, and then regenerate this schema definition.
5
+ #
6
+ # Note that this schema.rb definition is the authoritative source for your
7
+ # database schema. If you need to create the application database on another
8
+ # system, you should be using db:schema:load, not running all the migrations
9
+ # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10
+ # you'll amass, the slower it'll run and the greater likelihood for issues).
11
+ #
12
+ # It's strongly recommended to check this file into your version control system.
13
+
14
+ ActiveRecord::Schema.define(:version => 20111105072946) do
15
+
16
+ create_table "users", :force => true do |t|
17
+ t.string "name"
18
+ t.string "password"
19
+ t.string "email"
20
+ t.datetime "created_at"
21
+ t.datetime "updated_at"
22
+ t.string "sl_campaign"
23
+ end
24
+
25
+ end
Binary file