├── .gitignore ├── Gemfile ├── README.md ├── Rakefile ├── app └── models │ └── temporary_data.rb ├── lib ├── generators │ ├── rails_temporary_data_generator.rb │ └── templates │ │ └── migration.rb ├── rails_temporary_data.rb ├── rails_temporary_data │ ├── controller_helpers.rb │ ├── engine.rb │ └── version.rb └── tasks │ └── rails_temporary_data.rake ├── rails_temporary_data.gemspec └── test ├── controller_helpers_test.rb ├── dummy_rails_app ├── Rakefile ├── app │ ├── controllers │ │ ├── application_controller.rb │ │ └── dummy_controller.rb │ ├── helpers │ │ └── application_helper.rb │ └── views │ │ └── layouts │ │ └── application.html.erb ├── config.ru ├── config │ ├── application.rb │ ├── boot.rb │ ├── database.yml │ ├── environment.rb │ ├── environments │ │ ├── development.rb │ │ ├── production.rb │ │ └── test.rb │ ├── initializers │ │ ├── backtrace_silencers.rb │ │ ├── inflections.rb │ │ ├── mime_types.rb │ │ ├── secret_token.rb │ │ └── session_store.rb │ ├── locales │ │ └── en.yml │ └── routes.rb ├── db │ ├── migrate │ │ └── 20120309215634_create_temporary_data.rb │ └── test.sqlite3 └── public │ ├── 404.html │ ├── 422.html │ ├── 500.html │ ├── favicon.ico │ └── stylesheets │ └── .gitkeep ├── temporary_data_test.rb └── test_helper.rb /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | .bundle 3 | Gemfile.lock 4 | pkg/* 5 | .DS_Store 6 | test/dummy_rails_app/log/*.log -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | # Specify your gem's dependencies in rails_temporary_data.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | RailsTemporaryData 2 | ================== 3 | 4 | [![Gem Version](https://badge.fury.io/rb/rails_temporary_data.png)](http://badge.fury.io/rb/rails_temporary_data) 5 | 6 | Rails engine to simply save big temporary data (too big for session cookie store) in a database. It is great for a step-by-step wizard or similar functionality. 7 | 8 | Why 9 | --- 10 | While working on [Padbase](http://www.padbase.com) we needed [2 steps signup process](http://www.padbase.com/pads/new) (1. enter property info, 2. enter user info). Info entered in first step could get very large and we couldn't save it in a session because of [CookieOverflow](http://api.rubyonrails.org/classes/ActionDispatch/Cookies/CookieOverflow.html), didn't want to switch to ActiveRecord store and didn't want to save invalid property in database with the flag (partial validations, ...). Solution was to create separate table for this temporary data and RailsTemporaryData was born. 11 | 12 | **This way you get best from both worlds. Standard session data is still saved in a cookie and you can save larger amount of data in a database.** 13 | 14 | Install 15 | ------- 16 | 17 | Start by adding the gem to your application's Gemfile 18 | 19 | gem 'rails_temporary_data' 20 | 21 | Update your bundle 22 | 23 | bundle install 24 | 25 | Generate migration 26 | 27 | rails generate rails_temporary_data 28 | 29 | Run migration 30 | 31 | rake db:migrate 32 | 33 | Example 34 | -------- 35 | 36 | class DummyController < ApplicationController 37 | include RailsTemporaryData::ControllerHelpers 38 | 39 | def set_data 40 | set_tmp_data("some_key", { first_name: "Vlado", last_name: "Cingel", bio: "Very ... very long bio" }) 41 | ... 42 | end 43 | 44 | def get_data 45 | tmp_data = get_tmp_data("some_key").data 46 | # do something with tmp data 47 | first_name = tmp_data[:first_name] # => Vlado 48 | ... 49 | end 50 | 51 | def update_data 52 | tmp_data = get_tmp_data("some_key").data 53 | # do something with tmp data 54 | tmp_data[:first_name] = "Max" # => Max 55 | # and then save changes (update tmp data) 56 | update_tmp_data("some_key", tmp_data) # => { first_name: "Max", last_name: "Cingel", bio: "Very ... very long bio" } 57 | ... 58 | end 59 | 60 | end 61 | 62 | You can optionally set data expiry time (default is 2 days) 63 | 64 | class DummyController < ApplicationController 65 | include RailsTemporaryData::ControllerHelpers 66 | 67 | def set_data 68 | set_tmp_data("some_key", { bio: "Very ... very long bio" }, Time.now + 3.days) 69 | ... 70 | end 71 | 72 | end 73 | 74 | To clear data you don't need any more 75 | 76 | class DummyController < ApplicationController 77 | include RailsTemporaryData::ControllerHelpers 78 | 79 | def get_data 80 | tmp_data = get_tmp_data("some_key").data 81 | # do something with tmp data 82 | clear_tmp_data("some_key") 83 | end 84 | 85 | end 86 | 87 | To help you clear unwanted and/or expired data rake task is provided. You should set a cron job to call this task daily. 88 | 89 | rake rails_temporary_data:delete_expired 90 | 91 | 92 | TODO 93 | ---- 94 | 95 | * Default expires_at as configuration option 96 | * Generate initializer that will make RailsTemporaryData::ControllerHelpers available to all controllers 97 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | 3 | require 'rake/testtask' 4 | 5 | Rake::TestTask.new do |t| 6 | t.libs << 'test' 7 | t.test_files = FileList['test/**/*_test.rb'] 8 | end 9 | 10 | desc "Run tests" 11 | task :default => :test 12 | 13 | load "tasks/rails_temporary_data.rake" 14 | -------------------------------------------------------------------------------- /app/models/temporary_data.rb: -------------------------------------------------------------------------------- 1 | class TemporaryData < ActiveRecord::Base 2 | serialize :data 3 | before_create :set_default_expires_at 4 | 5 | scope :unexpired, lambda { where("expires_at > ?", Time.current) } 6 | scope :expired, lambda { where("expires_at < ?", Time.current) } 7 | 8 | def self.delete_expired 9 | expired.delete_all 10 | end 11 | 12 | def self.not_expired 13 | unexpired 14 | end 15 | 16 | private 17 | 18 | def set_default_expires_at 19 | self.expires_at = Time.current + 48.hours if expires_at.nil? || expires_at < Time.current 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/generators/rails_temporary_data_generator.rb: -------------------------------------------------------------------------------- 1 | require 'rails/generators' 2 | require 'rails/generators/migration' 3 | 4 | class RailsTemporaryDataGenerator < Rails::Generators::Base 5 | include Rails::Generators::Migration 6 | 7 | def self.source_root 8 | @source_root ||= File.join(File.dirname(__FILE__), 'templates') 9 | end 10 | 11 | def self.next_migration_number(dirname) 12 | if ActiveRecord::Base.timestamped_migrations 13 | Time.new.utc.strftime("%Y%m%d%H%M%S") 14 | else 15 | "%.3d" % (current_migration_number(dirname) + 1) 16 | end 17 | end 18 | 19 | def create_migration_file 20 | migration_template 'migration.rb', 'db/migrate/create_temporary_data.rb' 21 | end 22 | 23 | end -------------------------------------------------------------------------------- /lib/generators/templates/migration.rb: -------------------------------------------------------------------------------- 1 | class CreateTemporaryData < ActiveRecord::Migration[5.0] 2 | def change 3 | create_table :temporary_data do |t| 4 | t.text :data 5 | t.datetime :expires_at 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/rails_temporary_data.rb: -------------------------------------------------------------------------------- 1 | require "rails_temporary_data/version" 2 | require "rails_temporary_data/controller_helpers" 3 | require "rails_temporary_data/engine" 4 | 5 | module RailsTemporaryData 6 | # Your code goes here... 7 | end 8 | -------------------------------------------------------------------------------- /lib/rails_temporary_data/controller_helpers.rb: -------------------------------------------------------------------------------- 1 | module RailsTemporaryData 2 | module ControllerHelpers 3 | extend ActiveSupport::Concern 4 | 5 | def set_tmp_data(key, data, expires_at = nil) 6 | tmp_data = TemporaryData.create!(:data => data, :expires_at => expires_at) 7 | session[key] = tmp_data.id 8 | end 9 | 10 | def get_tmp_data(key) 11 | tmp_data = TemporaryData.unexpired.find_by_id(session[key]) 12 | session[key] = nil if tmp_data.nil? 13 | tmp_data 14 | end 15 | 16 | def clear_tmp_data(key) 17 | tmp_data = TemporaryData.unexpired.find_by_id(session[key]) 18 | session[key] = nil 19 | tmp_data.destroy if tmp_data 20 | end 21 | 22 | def update_tmp_data(key, data) 23 | tmp_data = TemporaryData.unexpired.find_by_id(session[key]) 24 | unless tmp_data.nil? 25 | tmp_data.data = data 26 | tmp_data.save! 27 | else 28 | session[key] = nil 29 | end 30 | end 31 | end 32 | end -------------------------------------------------------------------------------- /lib/rails_temporary_data/engine.rb: -------------------------------------------------------------------------------- 1 | module RailsTemporaryData 2 | class Engine < ::Rails::Engine 3 | 4 | config.after_initialize do 5 | ApplicationController.send(:include, RailsTemporaryData::ControllerHelpers) 6 | end 7 | 8 | end 9 | end -------------------------------------------------------------------------------- /lib/rails_temporary_data/version.rb: -------------------------------------------------------------------------------- 1 | module RailsTemporaryData 2 | VERSION = "1.0.1" 3 | end 4 | -------------------------------------------------------------------------------- /lib/tasks/rails_temporary_data.rake: -------------------------------------------------------------------------------- 1 | namespace :rails_temporary_data do 2 | 3 | desc "Removes expired entries from temporary data table" 4 | task :delete_expired => :environment do 5 | TemporaryData.delete_expired 6 | end 7 | 8 | end -------------------------------------------------------------------------------- /rails_temporary_data.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | $:.push File.expand_path("../lib", __FILE__) 3 | require "rails_temporary_data/version" 4 | 5 | Gem::Specification.new do |s| 6 | s.name = "rails_temporary_data" 7 | s.version = RailsTemporaryData::VERSION 8 | s.authors = ["Vlado Cingel"] 9 | s.email = ["vladocingel@gmail.com"] 10 | s.homepage = "https://github.com/vlado/rails_temporary_data" 11 | s.summary = %q{Rails engine to simply save temporary data that is too big for session in database} 12 | s.description = %q{Rails engine to simply save temporary data that is too big for session in database} 13 | 14 | s.rubyforge_project = "rails_temporary_data" 15 | 16 | s.files = `git ls-files`.split("\n") 17 | s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") 18 | s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } 19 | s.require_paths = ["lib"] 20 | 21 | # specify any dependencies here; for example: 22 | s.add_development_dependency("rake") 23 | s.add_development_dependency("sqlite3") 24 | 25 | s.add_dependency("rails") 26 | end 27 | -------------------------------------------------------------------------------- /test/controller_helpers_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ControllerHelpersTest < ActionController::TestCase 4 | 5 | def setup 6 | @controller = DummyController.new 7 | end 8 | 9 | test "set and get tmp data" do 10 | data = { "foo" => "bar" } 11 | expires_at = Time.current + 24.hours 12 | 13 | get :set_data, :data => data, :expires_at => expires_at 14 | get :get_data 15 | 16 | @tmp_data = assigns(:tmp_data) 17 | 18 | assert_equal 1, session["test_data"] 19 | assert_equal data, @tmp_data.data 20 | assert_equal expires_at.to_a, @tmp_data.expires_at.to_a 21 | end 22 | 23 | test "@tmp_data should not be returned (=nil) and session cleared if it is expired in the meantime" do 24 | data = { "foo" => "bar" } 25 | expires_at = Time.current + 1.second 26 | 27 | get :set_data, :data => { "foo" => "bar" }, :expires_at => expires_at 28 | sleep 1 29 | get :get_data 30 | 31 | assert_nil session["test_data"] 32 | assert_nil assigns(:tmp_data) 33 | end 34 | 35 | test "#clear_tmp_data shoould destroy both tmp data and sessions value" do 36 | get :set_data, :data => { "foo" => "bar" } 37 | assert_equal 1, TemporaryData.count 38 | get :clear_data 39 | assert_equal 0, TemporaryData.count 40 | assert_nil session["test_data"] 41 | end 42 | 43 | end 44 | -------------------------------------------------------------------------------- /test/dummy_rails_app/Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require File.expand_path('../config/application', __FILE__) 5 | require 'rake' 6 | 7 | Dummy::Application.load_tasks 8 | 9 | load "#{File.expand_path('../../..', __FILE__)}/lib/tasks/rails_temporary_data.rake" 10 | -------------------------------------------------------------------------------- /test/dummy_rails_app/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | protect_from_forgery 3 | end 4 | -------------------------------------------------------------------------------- /test/dummy_rails_app/app/controllers/dummy_controller.rb: -------------------------------------------------------------------------------- 1 | class DummyController < ApplicationController 2 | 3 | def set_data 4 | set_tmp_data("test_data", params[:data], params[:expires_at]) 5 | head :ok 6 | end 7 | 8 | def get_data 9 | @tmp_data = get_tmp_data("test_data") 10 | head :ok 11 | end 12 | 13 | def clear_data 14 | clear_tmp_data("test_data") 15 | head :ok 16 | end 17 | 18 | end -------------------------------------------------------------------------------- /test/dummy_rails_app/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /test/dummy_rails_app/app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Dummy 5 | <%= stylesheet_link_tag :all %> 6 | <%= javascript_include_tag :defaults %> 7 | <%= csrf_meta_tag %> 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/dummy_rails_app/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Dummy::Application 5 | -------------------------------------------------------------------------------- /test/dummy_rails_app/config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | require "active_model/railtie" 4 | require "active_record/railtie" 5 | require "action_controller/railtie" 6 | require "action_view/railtie" 7 | require "action_mailer/railtie" 8 | 9 | Bundler.require 10 | 11 | module Dummy 12 | class Application < Rails::Application 13 | # Settings in config/environments/* take precedence over those specified here. 14 | # Application configuration should go into files in config/initializers 15 | # -- all .rb files in that directory are automatically loaded. 16 | 17 | # Custom directories with classes and modules you want to be autoloadable. 18 | # config.autoload_paths += %W(#{config.root}/extras) 19 | 20 | # Only load the plugins named here, in the order given (default is alphabetical). 21 | # :all can be used as a placeholder for all plugins not explicitly named. 22 | # config.plugins = [ :exception_notification, :ssl_requirement, :all ] 23 | 24 | # Activate observers that should always be running. 25 | # config.active_record.observers = :cacher, :garbage_collector, :forum_observer 26 | 27 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 28 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 29 | # config.time_zone = 'Central Time (US & Canada)' 30 | 31 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 32 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 33 | # config.i18n.default_locale = :de 34 | 35 | # JavaScript files you want as :defaults (application.js is always included). 36 | # config.action_view.javascript_expansions[:defaults] = %w(jquery rails) 37 | 38 | # Configure the default encoding used in templates for Ruby 1.9. 39 | config.encoding = "utf-8" 40 | 41 | # Configure sensitive parameters which will be filtered from the log file. 42 | config.filter_parameters += [:password] 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /test/dummy_rails_app/config/boot.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | gemfile = File.expand_path('../../../../Gemfile', __FILE__) 3 | 4 | if File.exist?(gemfile) 5 | ENV['BUNDLE_GEMFILE'] = gemfile 6 | require 'bundler' 7 | Bundler.setup 8 | end 9 | 10 | $:.unshift File.expand_path('../../../../lib', __FILE__) -------------------------------------------------------------------------------- /test/dummy_rails_app/config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # gem install sqlite3-ruby (not necessary on OS X Leopard) 3 | development: 4 | adapter: sqlite3 5 | database: db/development.sqlite3 6 | pool: 5 7 | timeout: 5000 8 | 9 | # Warning: The database defined as "test" will be erased and 10 | # re-generated from your development database when you run "rake". 11 | # Do not set this db to the same as development or production. 12 | test: 13 | adapter: sqlite3 14 | database: db/test.sqlite3 15 | pool: 5 16 | timeout: 5000 17 | 18 | production: 19 | adapter: sqlite3 20 | database: ":memory:" 21 | -------------------------------------------------------------------------------- /test/dummy_rails_app/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the rails application 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the rails application 5 | Dummy::Application.initialize! 6 | -------------------------------------------------------------------------------- /test/dummy_rails_app/config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Dummy::Application.configure do 2 | # Settings specified here will take precedence over those in config/environment.rb 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the webserver when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Log error messages when you accidentally call methods on nil. 10 | config.whiny_nils = true 11 | 12 | # Show full error reports and disable caching 13 | config.consider_all_requests_local = true 14 | config.action_view.debug_rjs = true 15 | config.action_controller.perform_caching = false 16 | 17 | # Don't care if the mailer can't send 18 | config.action_mailer.raise_delivery_errors = false 19 | 20 | # Print deprecation notices to the Rails logger 21 | config.active_support.deprecation = :log 22 | 23 | # Only use best-standards-support built into browsers 24 | config.action_dispatch.best_standards_support = :builtin 25 | end 26 | 27 | -------------------------------------------------------------------------------- /test/dummy_rails_app/config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Dummy::Application.configure do 2 | # Settings specified here will take precedence over those in config/environment.rb 3 | 4 | # The production environment is meant for finished, "live" apps. 5 | # Code is not reloaded between requests 6 | config.cache_classes = true 7 | 8 | # Full error reports are disabled and caching is turned on 9 | config.consider_all_requests_local = false 10 | config.action_controller.perform_caching = true 11 | 12 | # Specifies the header that your server uses for sending files 13 | config.action_dispatch.x_sendfile_header = "X-Sendfile" 14 | 15 | # For nginx: 16 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' 17 | 18 | # If you have no front-end server that supports something like X-Sendfile, 19 | # just comment this out and Rails will serve the files 20 | 21 | # See everything in the log (default is :info) 22 | # config.log_level = :debug 23 | 24 | # Use a different logger for distributed setups 25 | # config.logger = SyslogLogger.new 26 | 27 | # Use a different cache store in production 28 | # config.cache_store = :mem_cache_store 29 | 30 | # Disable Rails's static asset server 31 | # In production, Apache or nginx will already do this 32 | config.serve_static_assets = false 33 | 34 | # Enable serving of images, stylesheets, and javascripts from an asset server 35 | # config.action_controller.asset_host = "http://assets.example.com" 36 | 37 | # Disable delivery errors, bad email addresses will be ignored 38 | # config.action_mailer.raise_delivery_errors = false 39 | 40 | # Enable threaded mode 41 | # config.threadsafe! 42 | 43 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 44 | # the I18n.default_locale when a translation can not be found) 45 | config.i18n.fallbacks = true 46 | 47 | # Send deprecation notices to registered listeners 48 | config.active_support.deprecation = :notify 49 | end 50 | -------------------------------------------------------------------------------- /test/dummy_rails_app/config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Dummy::Application.configure do 2 | # Settings specified here will take precedence over those in config/environment.rb 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Log error messages when you accidentally call methods on nil. 11 | config.whiny_nils = true 12 | 13 | # Show full error reports and disable caching 14 | config.consider_all_requests_local = true 15 | config.action_controller.perform_caching = false 16 | 17 | # Raise exceptions instead of rendering exception templates 18 | config.action_dispatch.show_exceptions = false 19 | 20 | # Disable request forgery protection in test environment 21 | config.action_controller.allow_forgery_protection = false 22 | 23 | # Tell Action Mailer not to deliver emails to the real world. 24 | # The :test delivery method accumulates sent emails in the 25 | # ActionMailer::Base.deliveries array. 26 | #config.action_mailer.delivery_method = :test 27 | 28 | # Use SQL instead of Active Record's schema dumper when creating the test database. 29 | # This is necessary if your schema can't be completely dumped by the schema dumper, 30 | # like if you have constraints or database-specific column types 31 | # config.active_record.schema_format = :sql 32 | 33 | # Print deprecation notices to the stderr 34 | config.active_support.deprecation = :stderr 35 | end 36 | -------------------------------------------------------------------------------- /test/dummy_rails_app/config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /test/dummy_rails_app/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format 4 | # (all these examples are active by default): 5 | # ActiveSupport::Inflector.inflections do |inflect| 6 | # inflect.plural /^(ox)$/i, '\1en' 7 | # inflect.singular /^(ox)en/i, '\1' 8 | # inflect.irregular 'person', 'people' 9 | # inflect.uncountable %w( fish sheep ) 10 | # end 11 | -------------------------------------------------------------------------------- /test/dummy_rails_app/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | # Mime::Type.register_alias "text/html", :iphone 6 | -------------------------------------------------------------------------------- /test/dummy_rails_app/config/initializers/secret_token.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | # Make sure the secret is at least 30 characters and all random, 6 | # no regular words or you'll be exposed to dictionary attacks. 7 | Dummy::Application.config.secret_token = '50777595d4b6041cfca51636cf4e262508f96cc081757729e7123d04a5abdf9e3554e4f519b71106e41c5146a9b07b5affd2e410af1130db3a7f4538b70e2429' 8 | -------------------------------------------------------------------------------- /test/dummy_rails_app/config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Dummy::Application.config.session_store :cookie_store, :key => '_dummy_session' 4 | 5 | # Use the database for sessions instead of the cookie-based default, 6 | # which shouldn't be used to store highly confidential information 7 | # (create the session table with "rake db:sessions:create") 8 | # Dummy::Application.config.session_store :active_record_store 9 | -------------------------------------------------------------------------------- /test/dummy_rails_app/config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Sample localization file for English. Add more files in this directory for other locales. 2 | # See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. 3 | 4 | en: 5 | hello: "Hello world" 6 | -------------------------------------------------------------------------------- /test/dummy_rails_app/config/routes.rb: -------------------------------------------------------------------------------- 1 | Dummy::Application.routes.draw do 2 | # The priority is based upon order of creation: 3 | # first created -> highest priority. 4 | 5 | # Sample of regular route: 6 | # match 'products/:id' => 'catalog#view' 7 | # Keep in mind you can assign values other than :controller and :action 8 | 9 | # Sample of named route: 10 | # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase 11 | # This route can be invoked with purchase_url(:id => product.id) 12 | 13 | # Sample resource route (maps HTTP verbs to controller actions automatically): 14 | # resources :products 15 | 16 | # Sample resource route with options: 17 | # resources :products do 18 | # member do 19 | # get 'short' 20 | # post 'toggle' 21 | # end 22 | # 23 | # collection do 24 | # get 'sold' 25 | # end 26 | # end 27 | 28 | # Sample resource route with sub-resources: 29 | # resources :products do 30 | # resources :comments, :sales 31 | # resource :seller 32 | # end 33 | 34 | # Sample resource route with more complex sub-resources 35 | # resources :products do 36 | # resources :comments 37 | # resources :sales do 38 | # get 'recent', :on => :collection 39 | # end 40 | # end 41 | 42 | # Sample resource route within a namespace: 43 | # namespace :admin do 44 | # # Directs /admin/products/* to Admin::ProductsController 45 | # # (app/controllers/admin/products_controller.rb) 46 | # resources :products 47 | # end 48 | 49 | # You can have the root of your site routed with "root" 50 | # just remember to delete public/index.html. 51 | # root :to => "welcome#index" 52 | 53 | # See how all your routes lay out with "rake routes" 54 | 55 | # This is a legacy wild controller route that's not recommended for RESTful applications. 56 | # Note: This route will make all actions in every controller accessible via GET requests. 57 | match ':controller(/:action(/:id(.:format)))' 58 | end 59 | -------------------------------------------------------------------------------- /test/dummy_rails_app/db/migrate/20120309215634_create_temporary_data.rb: -------------------------------------------------------------------------------- 1 | class CreateTemporaryData < ActiveRecord::Migration 2 | def change 3 | create_table :temporary_data do |t| 4 | t.text :data 5 | t.datetime :expires_at 6 | 7 | t.timestamps 8 | end 9 | end 10 | end -------------------------------------------------------------------------------- /test/dummy_rails_app/db/test.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vlado/rails_temporary_data/52f498199ea348f0f7298e7afce45fb8b2920866/test/dummy_rails_app/db/test.sqlite3 -------------------------------------------------------------------------------- /test/dummy_rails_app/public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The page you were looking for doesn't exist.

23 |

You may have mistyped the address or the page may have moved.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /test/dummy_rails_app/public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The change you wanted was rejected.

23 |

Maybe you tried to change something you didn't have access to.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /test/dummy_rails_app/public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

We're sorry, but something went wrong.

23 |

We've been notified about this issue and we'll take a look at it shortly.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /test/dummy_rails_app/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vlado/rails_temporary_data/52f498199ea348f0f7298e7afce45fb8b2920866/test/dummy_rails_app/public/favicon.ico -------------------------------------------------------------------------------- /test/dummy_rails_app/public/stylesheets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vlado/rails_temporary_data/52f498199ea348f0f7298e7afce45fb8b2920866/test/dummy_rails_app/public/stylesheets/.gitkeep -------------------------------------------------------------------------------- /test/temporary_data_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class TemporaryDataTest < ActiveSupport::TestCase 4 | 5 | test "data column is serialized" do 6 | tmp_data = TemporaryData.create(:data => { :first_name => "Vlado", :last_name => "Cingel" }) 7 | assert "Vlado", tmp_data.data[:first_name] 8 | end 9 | 10 | test "expires_at is set before create to time in future if blank (not provided) or set to past" do 11 | tmp_data_1 = TemporaryData.create(:data => {}) 12 | assert tmp_data_1.expires_at > Time.current 13 | tmp_data_2 = TemporaryData.create(:data => {}, :expires_at => Time.current - 1.hour) 14 | assert tmp_data_2.expires_at > Time.current 15 | end 16 | 17 | test "expires_at is not set before create if provided" do 18 | expires_at = Time.current + 5.hours 19 | tmp_data = TemporaryData.create(:data => {}, :expires_at => expires_at) 20 | assert_equal expires_at, tmp_data.expires_at 21 | end 22 | 23 | test "it should return all data (including expired) when no scope is defined" do 24 | tmp_data_1 = TemporaryData.create(:data => { :tmp_data => 1 }, :expires_at => Time.current + 1.second) 25 | tmp_data_2 = TemporaryData.create(:data => { :tmp_data => 2 }, :expires_at => Time.current + 1.hour) 26 | sleep 1 # wait for 1 second so tmp_data_1 expires 27 | tmp_data = TemporaryData.all 28 | assert tmp_data.include?(tmp_data_2) 29 | assert tmp_data.include?(tmp_data_1) 30 | end 31 | 32 | test "unexpired scope should return only not expired data by default" do 33 | tmp_data_1 = TemporaryData.create(:data => { :tmp_data => 1 }, :expires_at => Time.current + 1.second) 34 | tmp_data_2 = TemporaryData.create(:data => { :tmp_data => 2 }, :expires_at => Time.current + 1.hour) 35 | sleep 1 # wait for 1 second so tmp_data_1 expires 36 | tmp_data = TemporaryData.unexpired.all 37 | assert tmp_data.include?(tmp_data_2) 38 | assert !tmp_data.include?(tmp_data_1) 39 | end 40 | 41 | test "not_expired as alias for unexpired" do 42 | tmp_data_1 = TemporaryData.create(:data => { :tmp_data => 1 }, :expires_at => Time.current + 1.second) 43 | tmp_data_2 = TemporaryData.create(:data => { :tmp_data => 2 }, :expires_at => Time.current + 1.hour) 44 | sleep 1 # wait for 1 second so tmp_data_1 expires 45 | 46 | assert_equal TemporaryData.unexpired.all, TemporaryData.not_expired.all 47 | end 48 | 49 | test "expired scope should return expired data when no scope is defined" do 50 | tmp_data_1 = TemporaryData.create(:data => { :tmp_data => 1 }, :expires_at => Time.current + 1.second) 51 | tmp_data_2 = TemporaryData.create(:data => { :tmp_data => 2 }, :expires_at => Time.current + 1.hour) 52 | sleep 1 # wait for 1 second so tmp_data_1 expires 53 | tmp_data = TemporaryData.expired.all 54 | assert !tmp_data.include?(tmp_data_2) 55 | assert tmp_data.include?(tmp_data_1) 56 | end 57 | 58 | test "delete_expired method should delete all temporary data with expires_at field in the past" do 59 | tmp_data_1 = TemporaryData.create(:data => { :tmp_data => 1 }, :expires_at => Time.current + 1.second) 60 | tmp_data_2 = TemporaryData.create(:data => { :tmp_data => 2 }, :expires_at => Time.current + 1.hour) 61 | assert_equal 2, TemporaryData.unscoped.count 62 | 63 | sleep 1 # wait for 1 second so tmp_data_1 expires 64 | TemporaryData.delete_expired 65 | assert_equal [tmp_data_2], TemporaryData.all 66 | end 67 | 68 | end 69 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV["RAILS_ENV"] = "test" 2 | require 'dummy_rails_app/config/environment' 3 | require 'rails/test_help' 4 | 5 | Bundler.setup 6 | 7 | ActiveRecord::Migrator.migrate(File.expand_path("../dummy_rails_app/db/migrate/", __FILE__)) 8 | 9 | class ActiveSupport::TestCase 10 | # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order. 11 | # 12 | # Note: You'll currently still have to declare fixtures explicitly in integration tests 13 | # -- they do not yet inherit this setting 14 | fixtures :all 15 | 16 | # Add more helper methods to be used by all tests here... 17 | end 18 | --------------------------------------------------------------------------------