├── log └── .keep ├── app ├── mailers │ └── .keep ├── models │ ├── .keep │ ├── concerns │ │ └── .keep │ └── document.rb ├── assets │ ├── images │ │ └── .keep │ ├── stylesheets │ │ ├── documents.css.scss │ │ ├── application.css │ │ └── scaffolds.css.scss │ └── javascripts │ │ ├── documents.js.coffee │ │ └── application.js ├── controllers │ ├── concerns │ │ └── .keep │ ├── application_controller.rb │ └── documents_controller.rb ├── helpers │ ├── documents_helper.rb │ └── application_helper.rb └── views │ ├── documents │ ├── new.html.erb │ ├── show.json.jbuilder │ ├── index.json.jbuilder │ ├── _form.html.erb │ └── index.html.erb │ └── layouts │ └── application.html.erb ├── lib ├── assets │ └── .keep └── tasks │ └── .keep ├── public ├── favicon.ico ├── robots.txt ├── 500.html ├── 422.html └── 404.html ├── test ├── helpers │ ├── .keep │ └── documents_helper_test.rb ├── mailers │ └── .keep ├── models │ ├── .keep │ └── document_test.rb ├── controllers │ ├── .keep │ └── documents_controller_test.rb ├── fixtures │ ├── .keep │ └── documents.yml ├── integration │ └── .keep └── test_helper.rb ├── vendor └── assets │ ├── javascripts │ └── .keep │ └── stylesheets │ └── .keep ├── bin ├── rake ├── bundle └── rails ├── config.ru ├── config ├── environment.rb ├── initializers │ ├── session_store.rb │ ├── filter_parameter_logging.rb │ ├── mime_types.rb │ ├── backtrace_silencers.rb │ ├── wrap_parameters.rb │ ├── inflections.rb │ └── secret_token.rb ├── boot.rb ├── database.yml ├── locales │ └── en.yml ├── application.rb ├── environments │ ├── development.rb │ ├── test.rb │ └── production.rb └── routes.rb ├── Rakefile ├── db ├── migrate │ └── 20140602010533_create_documents.rb ├── seeds.rb └── schema.rb ├── README.md ├── .gitignore ├── LICENSE.md ├── Gemfile └── Gemfile.lock /log/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/mailers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/models/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/assets/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/tasks/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/helpers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/mailers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/models/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/images/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/controllers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/integration/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/models/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/controllers/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/assets/javascripts/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/assets/stylesheets/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/helpers/documents_helper.rb: -------------------------------------------------------------------------------- 1 | module DocumentsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative '../config/boot' 3 | require 'rake' 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /test/helpers/documents_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class DocumentsHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /app/views/documents/new.html.erb: -------------------------------------------------------------------------------- 1 |

New document

2 | 3 | <%= render 'form' %> 4 | 5 | <%= link_to 'Back', documents_path %> 6 | -------------------------------------------------------------------------------- /app/views/documents/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract! @document, :id, :filename, :content_type, :file_contents, :created_at, :updated_at 2 | -------------------------------------------------------------------------------- /bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path('../../config/application', __FILE__) 3 | require_relative '../config/boot' 4 | require 'rails/commands' 5 | -------------------------------------------------------------------------------- /test/models/document_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class DocumentTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /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 Rails.application 5 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the Rails application. 5 | Fileupload::Application.initialize! 6 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Fileupload::Application.config.session_store :cookie_store, key: '_fileupload_session' 4 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | # Set up gems listed in the Gemfile. 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | 4 | require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) 5 | -------------------------------------------------------------------------------- /app/views/documents/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array!(@documents) do |document| 2 | json.extract! document, :id, :filename, :content_type, :file_contents 3 | json.url document_url(document, format: :json) 4 | end 5 | -------------------------------------------------------------------------------- /app/assets/stylesheets/documents.css.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the Documents controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /app/assets/javascripts/documents.js.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | # Prevent CSRF attacks by raising an exception. 3 | # For APIs, you may want to use :null_session instead. 4 | protect_from_forgery with: :exception 5 | end 6 | -------------------------------------------------------------------------------- /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 | 6 | Fileupload::Application.load_tasks 7 | -------------------------------------------------------------------------------- /test/fixtures/documents.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | one: 4 | filename: MyString 5 | content_type: MyString 6 | file_contents: 7 | 8 | two: 9 | filename: MyString 10 | content_type: MyString 11 | file_contents: 12 | -------------------------------------------------------------------------------- /db/migrate/20140602010533_create_documents.rb: -------------------------------------------------------------------------------- 1 | class CreateDocuments < ActiveRecord::Migration 2 | def change 3 | create_table :documents do |t| 4 | t.string :filename 5 | t.string :content_type 6 | t.binary :file_contents 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Rails File Upload Example 2 | ========================= 3 | 4 | This is an example application to show how to do file upload in vanilla Rails 4 without the use of Paperclip. A live demo can be found [here](http://railsfileupload.herokuapp.com). There is also an accompanying [file upload tutorial](http://ryan.endacott.me/2014/06/10/rails-file-upload.html). 5 | -------------------------------------------------------------------------------- /db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should contain all the record creation needed to seed the database with its default values. 2 | # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). 3 | # 4 | # Examples: 5 | # 6 | # cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) 7 | # Mayor.create(name: 'Emanuel', city: cities.first) 8 | -------------------------------------------------------------------------------- /app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Vanilla Rails File Upload 5 | <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %> 6 | <%= javascript_include_tag "application", "data-turbolinks-track" => true %> 7 | <%= csrf_meta_tags %> 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile '~/.gitignore_global' 6 | 7 | # Ignore bundler config. 8 | /.bundle 9 | 10 | # Ignore the default SQLite database. 11 | /db/*.sqlite3 12 | /db/*.sqlite3-journal 13 | 14 | # Ignore all logfiles and tempfiles. 15 | /log/*.log 16 | /tmp 17 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV["RAILS_ENV"] ||= "test" 2 | require File.expand_path('../../config/environment', __FILE__) 3 | require 'rails/test_help' 4 | 5 | class ActiveSupport::TestCase 6 | ActiveRecord::Migration.check_pending! 7 | 8 | # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. 9 | # 10 | # Note: You'll currently still have to declare fixtures explicitly in integration tests 11 | # -- they do not yet inherit this setting 12 | fixtures :all 13 | 14 | # Add more helper methods to be used by all tests here... 15 | end 16 | -------------------------------------------------------------------------------- /app/views/documents/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_for(@document) do |f| %> 2 | <% if @document.errors.any? %> 3 |
4 |

<%= pluralize(@document.errors.count, "error") %> prohibited this document from being saved:

5 | 6 | 11 |
12 | <% end %> 13 | 14 |
15 | <%= f.file_field :file %> 16 |
17 |
18 | <%= f.submit %> 19 |
20 | <% end %> 21 | -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] if respond_to?(:wrap_parameters) 9 | end 10 | 11 | # To enable root element in JSON for ActiveRecord objects. 12 | # ActiveSupport.on_load(:active_record) do 13 | # self.include_root_in_json = true 14 | # end 15 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, 6 | * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the top of the 9 | * compiled file, but it's generally better to create a new file per style scope. 10 | * 11 | *= require_self 12 | *= require_tree . 13 | */ 14 | -------------------------------------------------------------------------------- /config/database.yml: -------------------------------------------------------------------------------- 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 26 | -------------------------------------------------------------------------------- /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. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, '\1en' 8 | # inflect.singular /^(ox)en/i, '\1' 9 | # inflect.irregular 'person', 'people' 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym 'RESTful' 16 | # end 17 | -------------------------------------------------------------------------------- /config/initializers/secret_token.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rake secret` to generate a secure secret key. 9 | 10 | # Make sure your secret_key_base is kept private 11 | # if you're sharing your code publicly. 12 | Fileupload::Application.config.secret_key_base = '9362380e7f518448d393ca173b455249d38cda983e7bfeef8c2e4afc8ab8fccd4b8e3915239a5ebb83588896c55fd4e25164825dd2ec1532136e63a019444f99' 13 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # To learn more, please read the Rails Internationalization guide 20 | # available at http://guides.rubyonrails.org/i18n.html. 21 | 22 | en: 23 | hello: "Hello world" 24 | -------------------------------------------------------------------------------- /app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, 5 | // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // compiled file. 9 | // 10 | // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details 11 | // about supported directives. 12 | // 13 | //= require jquery 14 | //= require jquery_ujs 15 | //= require turbolinks 16 | //= require_tree . 17 | -------------------------------------------------------------------------------- /app/models/document.rb: -------------------------------------------------------------------------------- 1 | class Document < ActiveRecord::Base 2 | 3 | validate :file_size_under_one_mb 4 | 5 | def initialize(params = {}) 6 | @file = params.delete(:file) 7 | super 8 | if @file 9 | self.filename = sanitize_filename(@file.original_filename) 10 | self.content_type = @file.content_type 11 | self.file_contents = @file.read 12 | end 13 | end 14 | 15 | private 16 | 17 | def sanitize_filename(filename) 18 | # Get only the filename, not the whole path (for IE) 19 | # Thanks to this article I just found for the tip: http://mattberther.com/2007/10/19/uploading-files-to-a-database-using-rails 20 | return File.basename(filename) 21 | end 22 | 23 | NUM_BYTES_IN_MEGABYTE = 1048576 24 | def file_size_under_one_mb 25 | if (@file.size.to_f / NUM_BYTES_IN_MEGABYTE) > 1 26 | errors.add(:file, 'File size cannot be over one megabyte.') 27 | end 28 | end 29 | 30 | end 31 | -------------------------------------------------------------------------------- /app/views/documents/index.html.erb: -------------------------------------------------------------------------------- 1 |

Vanilla File Upload in Rails 4

2 |

This is an example application to show how to do file upload in vanilla Rails 4. The source is on GitHub and an accompanying tutorial can be found here. Created by Ryan Endacott.

3 |

Listing documents

4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | <% @documents.each do |document| %> 16 | 17 | 18 | 19 | 20 | 21 | <% end %> 22 | 23 |
Filename
<%= document.filename %><%= button_to 'Download', document, method: :get %><%= button_to 'Destroy', document, method: :delete, data: { confirm: 'Are you sure?' } %>
24 | 25 |
26 | 27 | <%= link_to 'New Document', new_document_path %> 28 | -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | require 'rails/all' 4 | 5 | # Require the gems listed in Gemfile, including any gems 6 | # you've limited to :test, :development, or :production. 7 | Bundler.require(*Rails.groups) 8 | 9 | module Fileupload 10 | class Application < Rails::Application 11 | # Settings in config/environments/* take precedence over those specified here. 12 | # Application configuration should go into files in config/initializers 13 | # -- all .rb files in that directory are automatically loaded. 14 | 15 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 16 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 17 | # config.time_zone = 'Central Time (US & Canada)' 18 | 19 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 20 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 21 | # config.i18n.default_locale = :de 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /db/schema.rb: -------------------------------------------------------------------------------- 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 that you check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(version: 20140602010533) do 15 | 16 | create_table "documents", force: true do |t| 17 | t.string "filename" 18 | t.string "content_type" 19 | t.binary "file_contents" 20 | t.datetime "created_at" 21 | t.datetime "updated_at" 22 | end 23 | 24 | end 25 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Ryan Endacott 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Fileupload::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.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 web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Do not eager load code on boot. 10 | config.eager_load = false 11 | 12 | # Show full error reports and disable caching. 13 | config.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send. 17 | config.action_mailer.raise_delivery_errors = false 18 | 19 | # Print deprecation notices to the Rails logger. 20 | config.active_support.deprecation = :log 21 | 22 | # Raise an error on page load if there are pending migrations 23 | config.active_record.migration_error = :page_load 24 | 25 | # Debug mode disables concatenation and preprocessing of assets. 26 | # This option may cause significant delays in view rendering with a large 27 | # number of complex assets. 28 | config.assets.debug = true 29 | end 30 | -------------------------------------------------------------------------------- /app/assets/stylesheets/scaffolds.css.scss: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #fff; 3 | color: #333; 4 | font-family: verdana, arial, helvetica, sans-serif; 5 | font-size: 13px; 6 | line-height: 18px; 7 | } 8 | 9 | p, ol, ul, td { 10 | font-family: verdana, arial, helvetica, sans-serif; 11 | font-size: 13px; 12 | line-height: 18px; 13 | } 14 | 15 | pre { 16 | background-color: #eee; 17 | padding: 10px; 18 | font-size: 11px; 19 | } 20 | 21 | a { 22 | color: #000; 23 | &:visited { 24 | color: #666; 25 | } 26 | &:hover { 27 | color: #fff; 28 | background-color: #000; 29 | } 30 | } 31 | 32 | div { 33 | &.field, &.actions { 34 | margin-bottom: 10px; 35 | } 36 | } 37 | 38 | #notice { 39 | color: green; 40 | } 41 | 42 | .field_with_errors { 43 | padding: 2px; 44 | background-color: red; 45 | display: table; 46 | } 47 | 48 | #error_explanation { 49 | width: 450px; 50 | border: 2px solid red; 51 | padding: 7px; 52 | padding-bottom: 0; 53 | margin-bottom: 20px; 54 | background-color: #f0f0f0; 55 | h2 { 56 | text-align: left; 57 | font-weight: bold; 58 | padding: 5px 5px 5px 15px; 59 | font-size: 12px; 60 | margin: -7px; 61 | margin-bottom: 0px; 62 | background-color: #c00; 63 | color: #fff; 64 | } 65 | ul li { 66 | font-size: 12px; 67 | list-style: square; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /test/controllers/documents_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class DocumentsControllerTest < ActionController::TestCase 4 | setup do 5 | @document = documents(:one) 6 | end 7 | 8 | test "should get index" do 9 | get :index 10 | assert_response :success 11 | assert_not_nil assigns(:documents) 12 | end 13 | 14 | test "should get new" do 15 | get :new 16 | assert_response :success 17 | end 18 | 19 | test "should create document" do 20 | assert_difference('Document.count') do 21 | post :create, document: { content_type: @document.content_type, file_contents: @document.file_contents, filename: @document.filename } 22 | end 23 | 24 | assert_redirected_to document_path(assigns(:document)) 25 | end 26 | 27 | test "should show document" do 28 | get :show, id: @document 29 | assert_response :success 30 | end 31 | 32 | test "should get edit" do 33 | get :edit, id: @document 34 | assert_response :success 35 | end 36 | 37 | test "should update document" do 38 | patch :update, id: @document, document: { content_type: @document.content_type, file_contents: @document.file_contents, filename: @document.filename } 39 | assert_redirected_to document_path(assigns(:document)) 40 | end 41 | 42 | test "should destroy document" do 43 | assert_difference('Document.count', -1) do 44 | delete :destroy, id: @document 45 | end 46 | 47 | assert_redirected_to documents_path 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 48 | 49 | 50 | 51 | 52 |
53 |

We're sorry, but something went wrong.

54 |
55 |

If you are the application owner check the logs for more information.

56 | 57 | 58 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' 4 | gem 'rails', '4.0.4' 5 | 6 | group :development, :test do 7 | # Use sqlite3 as the database for Active Record 8 | gem 'sqlite3' 9 | end 10 | 11 | group :production do 12 | # Postgres for heroku 13 | gem 'pg' 14 | 15 | # Assets on heroku 16 | gem 'rails_12factor' 17 | end 18 | 19 | # Use SCSS for stylesheets 20 | gem 'sass-rails', '~> 4.0.2' 21 | 22 | # Use Uglifier as compressor for JavaScript assets 23 | gem 'uglifier', '>= 1.3.0' 24 | 25 | # Use CoffeeScript for .js.coffee assets and views 26 | gem 'coffee-rails', '~> 4.0.0' 27 | 28 | # See https://github.com/sstephenson/execjs#readme for more supported runtimes 29 | # gem 'therubyracer', platforms: :ruby 30 | 31 | # Use jquery as the JavaScript library 32 | gem 'jquery-rails' 33 | 34 | # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks 35 | gem 'turbolinks' 36 | 37 | # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder 38 | gem 'jbuilder', '~> 1.2' 39 | 40 | group :doc do 41 | # bundle exec rake doc:rails generates the API under doc/api. 42 | gem 'sdoc', require: false 43 | end 44 | 45 | # Use ActiveModel has_secure_password 46 | # gem 'bcrypt', '~> 3.1.7' 47 | 48 | # Use unicorn as the app server 49 | # gem 'unicorn' 50 | 51 | # Use Capistrano for deployment 52 | # gem 'capistrano', group: :development 53 | 54 | # Use debugger 55 | # gem 'debugger', group: [:development, :test] 56 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 48 | 49 | 50 | 51 | 52 |
53 |

The change you wanted was rejected.

54 |

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

55 |
56 |

If you are the application owner check the logs for more information.

57 | 58 | 59 | -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 48 | 49 | 50 | 51 | 52 |
53 |

The page you were looking for doesn't exist.

54 |

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

55 |
56 |

If you are the application owner check the logs for more information.

57 | 58 | 59 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Fileupload::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.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 | # Do not eager load code on boot. This avoids loading your whole application 11 | # just for the purpose of running a single test. If you are using a tool that 12 | # preloads Rails for running tests, you may have to set it to true. 13 | config.eager_load = false 14 | 15 | # Configure static asset server for tests with Cache-Control for performance. 16 | config.serve_static_assets = true 17 | config.static_cache_control = "public, max-age=3600" 18 | 19 | # Show full error reports and disable caching. 20 | config.consider_all_requests_local = true 21 | config.action_controller.perform_caching = false 22 | 23 | # Raise exceptions instead of rendering exception templates. 24 | config.action_dispatch.show_exceptions = false 25 | 26 | # Disable request forgery protection in test environment. 27 | config.action_controller.allow_forgery_protection = false 28 | 29 | # Tell Action Mailer not to deliver emails to the real world. 30 | # The :test delivery method accumulates sent emails in the 31 | # ActionMailer::Base.deliveries array. 32 | config.action_mailer.delivery_method = :test 33 | 34 | # Print deprecation notices to the stderr. 35 | config.active_support.deprecation = :stderr 36 | end 37 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Fileupload::Application.routes.draw do 2 | resources :documents 3 | 4 | root to: redirect('/documents') 5 | # The priority is based upon order of creation: first created -> highest priority. 6 | # See how all your routes lay out with "rake routes". 7 | 8 | # You can have the root of your site routed with "root" 9 | # root 'welcome#index' 10 | 11 | # Example of regular route: 12 | # get 'products/:id' => 'catalog#view' 13 | 14 | # Example of named route that can be invoked with purchase_url(id: product.id) 15 | # get 'products/:id/purchase' => 'catalog#purchase', as: :purchase 16 | 17 | # Example resource route (maps HTTP verbs to controller actions automatically): 18 | # resources :products 19 | 20 | # Example resource route with options: 21 | # resources :products do 22 | # member do 23 | # get 'short' 24 | # post 'toggle' 25 | # end 26 | # 27 | # collection do 28 | # get 'sold' 29 | # end 30 | # end 31 | 32 | # Example resource route with sub-resources: 33 | # resources :products do 34 | # resources :comments, :sales 35 | # resource :seller 36 | # end 37 | 38 | # Example resource route with more complex sub-resources: 39 | # resources :products do 40 | # resources :comments 41 | # resources :sales do 42 | # get 'recent', on: :collection 43 | # end 44 | # end 45 | 46 | # Example resource route with concerns: 47 | # concern :toggleable do 48 | # post 'toggle' 49 | # end 50 | # resources :posts, concerns: :toggleable 51 | # resources :photos, concerns: :toggleable 52 | 53 | # Example resource route within a namespace: 54 | # namespace :admin do 55 | # # Directs /admin/products/* to Admin::ProductsController 56 | # # (app/controllers/admin/products_controller.rb) 57 | # resources :products 58 | # end 59 | end 60 | -------------------------------------------------------------------------------- /app/controllers/documents_controller.rb: -------------------------------------------------------------------------------- 1 | class DocumentsController < ApplicationController 2 | before_action :set_document, only: [:show, :edit, :update, :destroy] 3 | 4 | # GET /documents 5 | # GET /documents.json 6 | def index 7 | @documents = Document.all 8 | end 9 | 10 | # GET /documents/1 11 | # GET /documents/1.json 12 | def show 13 | send_data(@document.file_contents, 14 | type: @document.content_type, 15 | filename: @document.filename) 16 | end 17 | 18 | # GET /documents/new 19 | def new 20 | @document = Document.new 21 | end 22 | 23 | # POST /documents 24 | # POST /documents.json 25 | def create 26 | @document = Document.new(document_params) 27 | 28 | respond_to do |format| 29 | if @document.save 30 | format.html { redirect_to documents_path, notice: 'Document was successfully created.' } 31 | format.json { render action: 'show', status: :created, location: @document } 32 | else 33 | format.html { render action: 'new' } 34 | format.json { render json: @document.errors, status: :unprocessable_entity } 35 | end 36 | end 37 | end 38 | 39 | # PATCH/PUT /documents/1 40 | # PATCH/PUT /documents/1.json 41 | def update 42 | respond_to do |format| 43 | if @document.update(document_params) 44 | format.html { redirect_to @document, notice: 'Document was successfully updated.' } 45 | format.json { head :no_content } 46 | else 47 | format.html { render action: 'edit' } 48 | format.json { render json: @document.errors, status: :unprocessable_entity } 49 | end 50 | end 51 | end 52 | 53 | # DELETE /documents/1 54 | # DELETE /documents/1.json 55 | def destroy 56 | @document.destroy 57 | respond_to do |format| 58 | format.html { redirect_to documents_url } 59 | format.json { head :no_content } 60 | end 61 | end 62 | 63 | private 64 | # Use callbacks to share common setup or constraints between actions. 65 | def set_document 66 | @document = Document.find(params[:id]) 67 | end 68 | 69 | # Never trust parameters from the scary internet, only allow the white list through. 70 | def document_params 71 | params.require(:document).permit(:file) 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | actionmailer (4.0.4) 5 | actionpack (= 4.0.4) 6 | mail (~> 2.5.4) 7 | actionpack (4.0.4) 8 | activesupport (= 4.0.4) 9 | builder (~> 3.1.0) 10 | erubis (~> 2.7.0) 11 | rack (~> 1.5.2) 12 | rack-test (~> 0.6.2) 13 | activemodel (4.0.4) 14 | activesupport (= 4.0.4) 15 | builder (~> 3.1.0) 16 | activerecord (4.0.4) 17 | activemodel (= 4.0.4) 18 | activerecord-deprecated_finders (~> 1.0.2) 19 | activesupport (= 4.0.4) 20 | arel (~> 4.0.0) 21 | activerecord-deprecated_finders (1.0.3) 22 | activesupport (4.0.4) 23 | i18n (~> 0.6, >= 0.6.9) 24 | minitest (~> 4.2) 25 | multi_json (~> 1.3) 26 | thread_safe (~> 0.1) 27 | tzinfo (~> 0.3.37) 28 | arel (4.0.2) 29 | builder (3.1.4) 30 | coffee-rails (4.0.1) 31 | coffee-script (>= 2.2.0) 32 | railties (>= 4.0.0, < 5.0) 33 | coffee-script (2.2.0) 34 | coffee-script-source 35 | execjs 36 | coffee-script-source (1.7.0) 37 | erubis (2.7.0) 38 | execjs (2.1.0) 39 | hike (1.2.3) 40 | i18n (0.6.9) 41 | jbuilder (1.5.3) 42 | activesupport (>= 3.0.0) 43 | multi_json (>= 1.2.0) 44 | jquery-rails (3.1.0) 45 | railties (>= 3.0, < 5.0) 46 | thor (>= 0.14, < 2.0) 47 | json (1.8.1) 48 | mail (2.5.4) 49 | mime-types (~> 1.16) 50 | treetop (~> 1.4.8) 51 | mime-types (1.25.1) 52 | minitest (4.7.5) 53 | multi_json (1.10.1) 54 | pg (0.17.1) 55 | polyglot (0.3.5) 56 | rack (1.5.2) 57 | rack-test (0.6.2) 58 | rack (>= 1.0) 59 | rails (4.0.4) 60 | actionmailer (= 4.0.4) 61 | actionpack (= 4.0.4) 62 | activerecord (= 4.0.4) 63 | activesupport (= 4.0.4) 64 | bundler (>= 1.3.0, < 2.0) 65 | railties (= 4.0.4) 66 | sprockets-rails (~> 2.0.0) 67 | rails_12factor (0.0.2) 68 | rails_serve_static_assets 69 | rails_stdout_logging 70 | rails_serve_static_assets (0.0.2) 71 | rails_stdout_logging (0.0.3) 72 | railties (4.0.4) 73 | actionpack (= 4.0.4) 74 | activesupport (= 4.0.4) 75 | rake (>= 0.8.7) 76 | thor (>= 0.18.1, < 2.0) 77 | rake (10.3.2) 78 | rdoc (4.1.1) 79 | json (~> 1.4) 80 | sass (3.2.19) 81 | sass-rails (4.0.3) 82 | railties (>= 4.0.0, < 5.0) 83 | sass (~> 3.2.0) 84 | sprockets (~> 2.8, <= 2.11.0) 85 | sprockets-rails (~> 2.0) 86 | sdoc (0.4.0) 87 | json (~> 1.8) 88 | rdoc (~> 4.0, < 5.0) 89 | sprockets (2.11.0) 90 | hike (~> 1.2) 91 | multi_json (~> 1.0) 92 | rack (~> 1.0) 93 | tilt (~> 1.1, != 1.3.0) 94 | sprockets-rails (2.0.1) 95 | actionpack (>= 3.0) 96 | activesupport (>= 3.0) 97 | sprockets (~> 2.8) 98 | sqlite3 (1.3.9) 99 | thor (0.19.1) 100 | thread_safe (0.3.4) 101 | tilt (1.4.1) 102 | treetop (1.4.15) 103 | polyglot 104 | polyglot (>= 0.3.1) 105 | turbolinks (2.2.2) 106 | coffee-rails 107 | tzinfo (0.3.39) 108 | uglifier (2.5.0) 109 | execjs (>= 0.3.0) 110 | json (>= 1.8.0) 111 | 112 | PLATFORMS 113 | ruby 114 | 115 | DEPENDENCIES 116 | coffee-rails (~> 4.0.0) 117 | jbuilder (~> 1.2) 118 | jquery-rails 119 | pg 120 | rails (= 4.0.4) 121 | rails_12factor 122 | sass-rails (~> 4.0.2) 123 | sdoc 124 | sqlite3 125 | turbolinks 126 | uglifier (>= 1.3.0) 127 | -------------------------------------------------------------------------------- /config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Fileupload::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # Code is not reloaded between requests. 5 | config.cache_classes = true 6 | 7 | # Eager load code on boot. This eager loads most of Rails and 8 | # your application in memory, allowing both thread web servers 9 | # and those relying on copy on write to perform better. 10 | # Rake tasks automatically ignore this option for performance. 11 | config.eager_load = true 12 | 13 | # Full error reports are disabled and caching is turned on. 14 | config.consider_all_requests_local = false 15 | config.action_controller.perform_caching = true 16 | 17 | # Enable Rack::Cache to put a simple HTTP cache in front of your application 18 | # Add `rack-cache` to your Gemfile before enabling this. 19 | # For large-scale production use, consider using a caching reverse proxy like nginx, varnish or squid. 20 | # config.action_dispatch.rack_cache = true 21 | 22 | # Disable Rails's static asset server (Apache or nginx will already do this). 23 | config.serve_static_assets = false 24 | 25 | # Compress JavaScripts and CSS. 26 | config.assets.js_compressor = :uglifier 27 | # config.assets.css_compressor = :sass 28 | 29 | # Do not fallback to assets pipeline if a precompiled asset is missed. 30 | config.assets.compile = false 31 | 32 | # Generate digests for assets URLs. 33 | config.assets.digest = true 34 | 35 | # Version of your assets, change this if you want to expire all your assets. 36 | config.assets.version = '1.0' 37 | 38 | # Specifies the header that your server uses for sending files. 39 | # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache 40 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx 41 | 42 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 43 | # config.force_ssl = true 44 | 45 | # Set to :debug to see everything in the log. 46 | config.log_level = :info 47 | 48 | # Prepend all log lines with the following tags. 49 | # config.log_tags = [ :subdomain, :uuid ] 50 | 51 | # Use a different logger for distributed setups. 52 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) 53 | 54 | # Use a different cache store in production. 55 | # config.cache_store = :mem_cache_store 56 | 57 | # Enable serving of images, stylesheets, and JavaScripts from an asset server. 58 | # config.action_controller.asset_host = "http://assets.example.com" 59 | 60 | # Precompile additional assets. 61 | # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. 62 | # config.assets.precompile += %w( search.js ) 63 | 64 | # Ignore bad email addresses and do not raise email delivery errors. 65 | # Set this to true and configure the email server for immediate delivery to raise delivery errors. 66 | # config.action_mailer.raise_delivery_errors = false 67 | 68 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 69 | # the I18n.default_locale when a translation can not be found). 70 | config.i18n.fallbacks = true 71 | 72 | # Send deprecation notices to registered listeners. 73 | config.active_support.deprecation = :notify 74 | 75 | # Disable automatic flushing of the log to improve performance. 76 | # config.autoflush_log = false 77 | 78 | # Use default logging formatter so that PID and timestamp are not suppressed. 79 | config.log_formatter = ::Logger::Formatter.new 80 | end 81 | --------------------------------------------------------------------------------