Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Adding basic contest

  • Loading branch information...
commit d1b200cbc47cbd3af257b220d7752d1499fa3cc9 1 parent a609b16
@andmej authored
View
2  Gemfile
@@ -7,6 +7,7 @@ gem 'rails', '3.1.0'
gem 'sqlite3'
+gem 'nifty-generators'
# Gems used only for assets and not required
# in production environments by default.
@@ -31,3 +32,4 @@ group :test do
# Pretty printed test output
gem 'turn', :require => false
end
+gem "mocha", :group => :test
View
6 Gemfile.lock
@@ -53,8 +53,12 @@ GEM
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
+ metaclass (0.0.1)
mime-types (1.16)
+ mocha (0.10.0)
+ metaclass (~> 0.0.1)
multi_json (1.0.3)
+ nifty-generators (0.4.6)
polyglot (0.3.2)
rack (1.3.3)
rack-cache (1.0.3)
@@ -112,6 +116,8 @@ PLATFORMS
DEPENDENCIES
coffee-rails (~> 3.1.0)
jquery-rails
+ mocha
+ nifty-generators
rails (= 3.1.0)
sass-rails (~> 3.1.0)
sqlite3
View
7 app/assets/stylesheets/application.css
@@ -1,7 +0,0 @@
-/*
- * This is a manifest file that'll automatically include all the stylesheets available in this directory
- * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
- * the top of the compiled file, but it's generally better to create a new file per style scope.
- *= require_self
- *= require_tree .
-*/
View
1  app/assets/stylesheets/application.css.scss
@@ -0,0 +1 @@
+@import 'scaffold';
View
75 app/assets/stylesheets/scaffold.css.scss
@@ -0,0 +1,75 @@
+body {
+ background-color: #4B7399;
+ font-family: Verdana, Helvetica, Arial;
+ font-size: 14px;
+}
+
+a img {
+ border: none;
+}
+
+a {
+ color: #0000FF;
+}
+
+.clear {
+ clear: both;
+ height: 0;
+ overflow: hidden;
+}
+
+#container {
+ width: 75%;
+ margin: 0 auto;
+ background-color: #FFF;
+ padding: 20px 40px;
+ border: solid 1px black;
+ margin-top: 20px;
+}
+
+#flash_notice, #flash_error, #flash_alert {
+ padding: 5px 8px;
+ margin: 10px 0;
+}
+
+#flash_notice {
+ background-color: #CFC;
+ border: solid 1px #6C6;
+}
+
+#flash_error, #flash_alert {
+ background-color: #FCC;
+ border: solid 1px #C66;
+}
+
+.fieldWithErrors {
+ display: inline;
+}
+
+.error_messages {
+ width: 400px;
+ border: 2px solid #CF0000;
+ padding: 0px;
+ padding-bottom: 12px;
+ margin-bottom: 20px;
+ background-color: #f0f0f0;
+ font-size: 12px;
+}
+
+.error_messages h2 {
+ text-align: left;
+ font-weight: bold;
+ padding: 5px 10px;
+ font-size: 12px;
+ margin: 0;
+ background-color: #c00;
+ color: #fff;
+}
+
+.error_messages p {
+ margin: 8px 10px;
+}
+
+.error_messages ul {
+ margin: 0;
+}
View
41 app/controllers/contests_controller.rb
@@ -0,0 +1,41 @@
+class ContestsController < ApplicationController
+ def index
+ @contests = Contest.all
+ end
+
+ def show
+ @contest = Contest.find(params[:id])
+ end
+
+ def new
+ @contest = Contest.new
+ end
+
+ def create
+ @contest = Contest.new(params[:contest])
+ if @contest.save
+ redirect_to @contest, :notice => "Successfully created contest."
+ else
+ render :action => 'new'
+ end
+ end
+
+ def edit
+ @contest = Contest.find(params[:id])
+ end
+
+ def update
+ @contest = Contest.find(params[:id])
+ if @contest.update_attributes(params[:contest])
+ redirect_to @contest, :notice => "Successfully updated contest."
+ else
+ render :action => 'edit'
+ end
+ end
+
+ def destroy
+ @contest = Contest.find(params[:id])
+ @contest.destroy
+ redirect_to contests_url, :notice => "Successfully destroyed contest."
+ end
+end
View
2  app/helpers/contests_helper.rb
@@ -0,0 +1,2 @@
+module ContestsHelper
+end
View
23 app/helpers/error_messages_helper.rb
@@ -0,0 +1,23 @@
+module ErrorMessagesHelper
+ # Render error messages for the given objects. The :message and :header_message options are allowed.
+ def error_messages_for(*objects)
+ options = objects.extract_options!
+ options[:header_message] ||= I18n.t(:"activerecord.errors.header", :default => "Invalid Fields")
+ options[:message] ||= I18n.t(:"activerecord.errors.message", :default => "Correct the following errors and try again.")
+ messages = objects.compact.map { |o| o.errors.full_messages }.flatten
+ unless messages.empty?
+ content_tag(:div, :class => "error_messages") do
+ list_items = messages.map { |msg| content_tag(:li, msg) }
+ content_tag(:h2, options[:header_message]) + content_tag(:p, options[:message]) + content_tag(:ul, list_items.join.html_safe)
+ end
+ end
+ end
+
+ module FormBuilderAdditions
+ def error_messages(options = {})
+ @template.error_messages_for(@object, options)
+ end
+ end
+end
+
+ActionView::Helpers::FormBuilder.send(:include, ErrorMessagesHelper::FormBuilderAdditions)
View
22 app/helpers/layout_helper.rb
@@ -0,0 +1,22 @@
+# These helper methods can be called in your template to set variables to be used in the layout
+# This module should be included in all views globally,
+# to do so you may need to add this line to your ApplicationController
+# helper :layout
+module LayoutHelper
+ def title(page_title, show_title = true)
+ content_for(:title) { h(page_title.to_s) }
+ @show_title = show_title
+ end
+
+ def show_title?
+ @show_title
+ end
+
+ def stylesheet(*args)
+ content_for(:head) { stylesheet_link_tag(*args) }
+ end
+
+ def javascript(*args)
+ content_for(:head) { javascript_include_tag(*args) }
+ end
+end
View
13 app/models/contest.rb
@@ -0,0 +1,13 @@
+class Contest < ActiveRecord::Base
+ attr_accessible :name, :start_date, :end_date
+ validates :name, :start_date, :end_date, :presence => true
+ validate :start_date_must_be_before_end_date
+
+ protected
+
+ def start_date_must_be_before_end_date
+ if start_date.present? and end_date.present?
+ errors.add(:start_date, "must be before end date") unless start_date < end_date
+ end
+ end
+end
View
16 app/views/contests/_form.html.erb
@@ -0,0 +1,16 @@
+<%= form_for @contest do |f| %>
+ <%= f.error_messages %>
+ <p>
+ <%= f.label :name %><br />
+ <%= f.text_field :name %>
+ </p>
+ <p>
+ <%= f.label :start_date %><br />
+ <%= f.datetime_select :start_date %>
+ </p>
+ <p>
+ <%= f.label :end_date %><br />
+ <%= f.datetime_select :end_date %>
+ </p>
+ <p><%= f.submit %></p>
+<% end %>
View
8 app/views/contests/edit.html.erb
@@ -0,0 +1,8 @@
+<% title "Edit Contest" %>
+
+<%= render 'form' %>
+
+<p>
+ <%= link_to "Show", @contest %> |
+ <%= link_to "View All", contests_path %>
+</p>
View
21 app/views/contests/index.html.erb
@@ -0,0 +1,21 @@
+<% title "Contests" %>
+
+<table>
+ <tr>
+ <th>Name</th>
+ <th>Start Date</th>
+ <th>End Date</th>
+ </tr>
+ <% for contest in @contests %>
+ <tr>
+ <td><%= contest.name %></td>
+ <td><%= contest.start_date %></td>
+ <td><%= contest.end_date %></td>
+ <td><%= link_to "Show", contest %></td>
+ <td><%= link_to "Edit", edit_contest_path(contest) %></td>
+ <td><%= link_to "Destroy", contest, :confirm => 'Are you sure?', :method => :delete %></td>
+ </tr>
+ <% end %>
+</table>
+
+<p><%= link_to "New Contest", new_contest_path %></p>
View
5 app/views/contests/new.html.erb
@@ -0,0 +1,5 @@
+<% title "New Contest" %>
+
+<%= render 'form' %>
+
+<p><%= link_to "Back to List", contests_path %></p>
View
20 app/views/contests/show.html.erb
@@ -0,0 +1,20 @@
+<% title "Contest" %>
+
+<p>
+ <strong>Name:</strong>
+ <%= @contest.name %>
+</p>
+<p>
+ <strong>Start Date:</strong>
+ <%= @contest.start_date %>
+</p>
+<p>
+ <strong>End Date:</strong>
+ <%= @contest.end_date %>
+</p>
+
+<p>
+ <%= link_to "Edit", edit_contest_path(@contest) %> |
+ <%= link_to "Destroy", @contest, :confirm => 'Are you sure?', :method => :delete %> |
+ <%= link_to "View All", contests_path %>
+</p>
View
27 app/views/layouts/application.html.erb
@@ -1,14 +1,19 @@
<!DOCTYPE html>
<html>
-<head>
- <title>Contests</title>
- <%= stylesheet_link_tag "application" %>
- <%= javascript_include_tag "application" %>
- <%= csrf_meta_tags %>
-</head>
-<body>
-
-<%= yield %>
-
-</body>
+ <head>
+ <title><%= content_for?(:title) ? yield(:title) : "Untitled" %></title>
+ <%= stylesheet_link_tag "application" %>
+ <%= javascript_include_tag :defaults %>
+ <%= csrf_meta_tag %>
+ <%= yield(:head) %>
+ </head>
+ <body>
+ <div id="container">
+ <% flash.each do |name, msg| %>
+ <%= content_tag :div, msg, :id => "flash_#{name}" %>
+ <% end %>
+ <%= content_tag :h1, yield(:title) if show_title? %>
+ <%= yield %>
+ </div>
+ </body>
</html>
View
2  config/application.rb
@@ -27,7 +27,7 @@ class Application < Rails::Application
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
- # config.time_zone = 'Central Time (US & Canada)'
+ config.time_zone = 'Bogota'
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
View
58 config/routes.rb
@@ -1,58 +1,4 @@
Contests::Application.routes.draw do
- # The priority is based upon order of creation:
- # first created -> highest priority.
-
- # Sample of regular route:
- # match 'products/:id' => 'catalog#view'
- # Keep in mind you can assign values other than :controller and :action
-
- # Sample of named route:
- # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
- # This route can be invoked with purchase_url(:id => product.id)
-
- # Sample resource route (maps HTTP verbs to controller actions automatically):
- # resources :products
-
- # Sample resource route with options:
- # resources :products do
- # member do
- # get 'short'
- # post 'toggle'
- # end
- #
- # collection do
- # get 'sold'
- # end
- # end
-
- # Sample resource route with sub-resources:
- # resources :products do
- # resources :comments, :sales
- # resource :seller
- # end
-
- # Sample resource route with more complex sub-resources
- # resources :products do
- # resources :comments
- # resources :sales do
- # get 'recent', :on => :collection
- # end
- # end
-
- # Sample resource route within a namespace:
- # namespace :admin do
- # # Directs /admin/products/* to Admin::ProductsController
- # # (app/controllers/admin/products_controller.rb)
- # resources :products
- # end
-
- # You can have the root of your site routed with "root"
- # just remember to delete public/index.html.
- # root :to => 'welcome#index'
-
- # See how all your routes lay out with "rake routes"
-
- # This is a legacy wild controller route that's not recommended for RESTful applications.
- # Note: This route will make all actions in every controller accessible via GET requests.
- # match ':controller(/:action(/:id(.:format)))'
+ resources :contests
+ root :to => "contests#index"
end
View
14 db/migrate/20110926010221_create_contests.rb
@@ -0,0 +1,14 @@
+class CreateContests < ActiveRecord::Migration
+ def self.up
+ create_table :contests do |t|
+ t.string :name
+ t.datetime :start_date
+ t.datetime :end_date
+ t.timestamps
+ end
+ end
+
+ def self.down
+ drop_table :contests
+ end
+end
View
24 db/schema.rb
@@ -0,0 +1,24 @@
+# encoding: UTF-8
+# This file is auto-generated from the current state of the database. Instead
+# of editing this file, please use the migrations feature of Active Record to
+# incrementally modify your database, and then regenerate this schema definition.
+#
+# Note that this schema.rb definition is the authoritative source for your
+# database schema. If you need to create the application database on another
+# system, you should be using db:schema:load, not running all the migrations
+# from scratch. The latter is a flawed and unsustainable approach (the more migrations
+# you'll amass, the slower it'll run and the greater likelihood for issues).
+#
+# It's strongly recommended to check this file into your version control system.
+
+ActiveRecord::Schema.define(:version => 20110926010221) do
+
+ create_table "contests", :force => true do |t|
+ t.string "name"
+ t.datetime "start_date"
+ t.datetime "end_date"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
+end
View
241 public/index.html
@@ -1,241 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <title>Ruby on Rails: Welcome aboard</title>
- <style type="text/css" media="screen">
- body {
- margin: 0;
- margin-bottom: 25px;
- padding: 0;
- background-color: #f0f0f0;
- font-family: "Lucida Grande", "Bitstream Vera Sans", "Verdana";
- font-size: 13px;
- color: #333;
- }
-
- h1 {
- font-size: 28px;
- color: #000;
- }
-
- a {color: #03c}
- a:hover {
- background-color: #03c;
- color: white;
- text-decoration: none;
- }
-
-
- #page {
- background-color: #f0f0f0;
- width: 750px;
- margin: 0;
- margin-left: auto;
- margin-right: auto;
- }
-
- #content {
- float: left;
- background-color: white;
- border: 3px solid #aaa;
- border-top: none;
- padding: 25px;
- width: 500px;
- }
-
- #sidebar {
- float: right;
- width: 175px;
- }
-
- #footer {
- clear: both;
- }
-
- #header, #about, #getting-started {
- padding-left: 75px;
- padding-right: 30px;
- }
-
-
- #header {
- background-image: url("/assets/rails.png");
- background-repeat: no-repeat;
- background-position: top left;
- height: 64px;
- }
- #header h1, #header h2 {margin: 0}
- #header h2 {
- color: #888;
- font-weight: normal;
- font-size: 16px;
- }
-
-
- #about h3 {
- margin: 0;
- margin-bottom: 10px;
- font-size: 14px;
- }
-
- #about-content {
- background-color: #ffd;
- border: 1px solid #fc0;
- margin-left: -55px;
- margin-right: -10px;
- }
- #about-content table {
- margin-top: 10px;
- margin-bottom: 10px;
- font-size: 11px;
- border-collapse: collapse;
- }
- #about-content td {
- padding: 10px;
- padding-top: 3px;
- padding-bottom: 3px;
- }
- #about-content td.name {color: #555}
- #about-content td.value {color: #000}
-
- #about-content ul {
- padding: 0;
- list-style-type: none;
- }
-
- #about-content.failure {
- background-color: #fcc;
- border: 1px solid #f00;
- }
- #about-content.failure p {
- margin: 0;
- padding: 10px;
- }
-
-
- #getting-started {
- border-top: 1px solid #ccc;
- margin-top: 25px;
- padding-top: 15px;
- }
- #getting-started h1 {
- margin: 0;
- font-size: 20px;
- }
- #getting-started h2 {
- margin: 0;
- font-size: 14px;
- font-weight: normal;
- color: #333;
- margin-bottom: 25px;
- }
- #getting-started ol {
- margin-left: 0;
- padding-left: 0;
- }
- #getting-started li {
- font-size: 18px;
- color: #888;
- margin-bottom: 25px;
- }
- #getting-started li h2 {
- margin: 0;
- font-weight: normal;
- font-size: 18px;
- color: #333;
- }
- #getting-started li p {
- color: #555;
- font-size: 13px;
- }
-
-
- #sidebar ul {
- margin-left: 0;
- padding-left: 0;
- }
- #sidebar ul h3 {
- margin-top: 25px;
- font-size: 16px;
- padding-bottom: 10px;
- border-bottom: 1px solid #ccc;
- }
- #sidebar li {
- list-style-type: none;
- }
- #sidebar ul.links li {
- margin-bottom: 5px;
- }
-
- .filename {
- font-style: italic;
- }
- </style>
- <script type="text/javascript">
- function about() {
- info = document.getElementById('about-content');
- if (window.XMLHttpRequest)
- { xhr = new XMLHttpRequest(); }
- else
- { xhr = new ActiveXObject("Microsoft.XMLHTTP"); }
- xhr.open("GET","rails/info/properties",false);
- xhr.send("");
- info.innerHTML = xhr.responseText;
- info.style.display = 'block'
- }
- </script>
- </head>
- <body>
- <div id="page">
- <div id="sidebar">
- <ul id="sidebar-items">
- <li>
- <h3>Browse the documentation</h3>
- <ul class="links">
- <li><a href="http://guides.rubyonrails.org/">Rails Guides</a></li>
- <li><a href="http://api.rubyonrails.org/">Rails API</a></li>
- <li><a href="http://www.ruby-doc.org/core/">Ruby core</a></li>
- <li><a href="http://www.ruby-doc.org/stdlib/">Ruby standard library</a></li>
- </ul>
- </li>
- </ul>
- </div>
-
- <div id="content">
- <div id="header">
- <h1>Welcome aboard</h1>
- <h2>You&rsquo;re riding Ruby on Rails!</h2>
- </div>
-
- <div id="about">
- <h3><a href="rails/info/properties" onclick="about(); return false">About your application&rsquo;s environment</a></h3>
- <div id="about-content" style="display: none"></div>
- </div>
-
- <div id="getting-started">
- <h1>Getting started</h1>
- <h2>Here&rsquo;s how to get rolling:</h2>
-
- <ol>
- <li>
- <h2>Use <code>rails generate</code> to create your models and controllers</h2>
- <p>To see all available options, run it without parameters.</p>
- </li>
-
- <li>
- <h2>Set up a default route and remove <span class="filename">public/index.html</span></h2>
- <p>Routes are set up in <span class="filename">config/routes.rb</span>.</p>
- </li>
-
- <li>
- <h2>Create your database</h2>
- <p>Run <code>rake db:create</code> to create your database. If you're not using SQLite (the default), edit <span class="filename">config/database.yml</span> with your username and password.</p>
- </li>
- </ol>
- </div>
- </div>
-
- <div id="footer">&nbsp;</div>
- </div>
- </body>
-</html>
View
9 test/fixtures/contests.yml
@@ -0,0 +1,9 @@
+one:
+ name: MyString
+ start_date: 2011-09-25 20:02:20
+ end_date: 2011-09-25 20:02:20
+
+two:
+ name: MyString
+ start_date: 2011-09-25 20:02:20
+ end_date: 2011-09-25 20:02:20
View
54 test/functional/contests_controller_test.rb
@@ -0,0 +1,54 @@
+require 'test_helper'
+
+class ContestsControllerTest < ActionController::TestCase
+ def test_index
+ get :index
+ assert_template 'index'
+ end
+
+ def test_show
+ get :show, :id => Contest.first
+ assert_template 'show'
+ end
+
+ def test_new
+ get :new
+ assert_template 'new'
+ end
+
+ def test_create_invalid
+ Contest.any_instance.stubs(:valid?).returns(false)
+ post :create
+ assert_template 'new'
+ end
+
+ def test_create_valid
+ Contest.any_instance.stubs(:valid?).returns(true)
+ post :create
+ assert_redirected_to contest_url(assigns(:contest))
+ end
+
+ def test_edit
+ get :edit, :id => Contest.first
+ assert_template 'edit'
+ end
+
+ def test_update_invalid
+ Contest.any_instance.stubs(:valid?).returns(false)
+ put :update, :id => Contest.first
+ assert_template 'edit'
+ end
+
+ def test_update_valid
+ Contest.any_instance.stubs(:valid?).returns(true)
+ put :update, :id => Contest.first
+ assert_redirected_to contest_url(assigns(:contest))
+ end
+
+ def test_destroy
+ contest = Contest.first
+ delete :destroy, :id => contest
+ assert_redirected_to contests_url
+ assert !Contest.exists?(contest.id)
+ end
+end
View
7 test/unit/contest_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class ContestTest < ActiveSupport::TestCase
+ def test_should_be_valid
+ assert Contest.new.valid?
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.