bobfirestone/rw_todo_app
Folders and files
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Repository files navigation
RubyWeekend Application Tutorial:
Lines beginning with a $ are commands to be run from the command line
indented text indicates text to be inserted into some file.
********CREATE A NEW RAILS APP*********
$ rails new todo_app
$ cd todo_app
********START THE SERVER********
$ rails server
You should see the "Rails Start Page"
stop the server "ctrl-c"
********CREATE A HOMEPAGE & GET RID OF RAILS START PAGE********
$ rails g controller welcome index
$ rm public/index.html
config/routes.rb
uncomment line #53 "root :to => 'welcome#index'"
$ rails s
http://localhost:3000
stop the server "ctrl-c"
********CREATE SOME TODO'S********
$ rails g scaffold todo title:string description:text
$ bundle exec rake db:migrate
$ rails s
http://localhost:3000/todos/
********VALIDATION********
app/models/todo.rb
attr_accessible :title, :description
validates_presence_of :title
stop the server "ctrl-c"
********PRETTY TODO's USING TWITTER BOOTSTRAP********
Gemfile
gem 'twitter-bootstrap-rails'
$ bundle install
$ rails g bootstrap:install
$ rails g bootstrap:layout application fixed
Overwrite ?
Y
$ rails g bootstrap:themed todos
Overwrite ?
Y to all
CHANGE "LINK 1" TO OPEN
app/layouts/application.html.erb
<li><%= link_to "Open", todos_path %></li>
Change
<a class="brand" href="#">TodoApp</a>
to
<a class="brand" href=<%= root_path %>>RwTodoApp</a>
Remove Scaffod Stylesheet
$ rm app/assets/stylesheets/scaffolds.css.scss
$ rails s
http://localhost:3000
stop the server "ctrl-c"
********ADDING PRIORITY TO TODOS********
$ rails g migration add_priority_to_todos priority:integer
$ bundle exec rake db:migrate
Add priority to form
views/todos/_form.html.erb
<div class="control-group">
<%= f.label :priority, :class => 'control-label' %>
<div class="controls">
<%= f.text_field :priority, :class => 'text_field' %>
</div>
</div>
views/todos/index.html.erb
remove from <th> id, created_at
change one th & td to priority
make title link_to show action
views/todos/show.html.erb
<p>
<strong><%= model_class.human_attribute_name(:priority) %>:</strong><%= @todo.priority %>
</p>
model/todo.rb
default_scope order("priority DESC")
attr_accessible :title, :description, :priority
$ rails s
http://localhost:3000/todos
********ADD A TODO********
stop the server "ctrl-c"
********ADDING NOTES TO TODO'S********
$ rails g model note note:text todo_id:integer
$ bundle exec rake db:migrate
$ rails s
http://localhost:3000/todos
********ACTIVE RECORD ASSOCIATIONS********
model/todo.rb
has_many :notes
model/note.rb
belongs_to :todo
********SHOW TODO NOTES ON TODO PAGE********
controllers/todos_controller
show
@notes = @todo.notes.all # on line 17
views/todos/show.html.erb
<h3>Notes</h3>
<ul>
<% @notes.each do |note| %>
<li><%= note.note %> <em><%= note.created_at %><em></li>
<% end %>
</ul>
stop the server "ctrl-c"
********ADD SOME NOTES IN THE CONSOLE********
$ rails console
> n = Note.create(note: "It's a note", todo_id: 1)
View the page and the note should be there
> exit
$ rails s
http://localhost:3000/todos
stop the server "ctrl-c"
$ rails console
> t = Todo.find(1)
> x = t.notes.build(note: "note made by build")
> x.save
View the page again and the second note will be there
> exit
$ rails s
http://localhost:3000/todos
CREATE NOTE FROM TODO SHOW PAGE
1. Create a notes_controller
2. add routing for the controller
3. add a notes form on the show page
********NOTES CONTROLLER********
$ rails g controller notes create
controllers/notes_controller
def create
@todo = Todo.find(params[:todo_id])
@note = @todo.notes.build(params[:note])
if @note.save
redirect_to todo_path(@todo)
else
redirect_to todo_path(@todo)
end
end
********ROUTING TO THE CONTROLLER********
config/routes.rb
resources :todos do
resources :notes
end
********FORM ON TODO SHOW PAGE********
views/todos/show.html.erb
<%= form_for([@todo, @todo.notes.build]) do |f| %>
<%= f.label :note %>
<%= f.text_field :note %>
<%= f.submit %>
<% end %>
$ rails s
http://localhost:3000/todos/1
reload the page & the form should be there
********VALIDATE PRESENCE OF NOTE********
attr_accessible :note
validates_presence_of :note
********STAMP FOR SHOWING DATES********
stop the server "ctrl-c"
Gemfile
gem 'stamp'
$ bundle
views/todos/show.html.erb
<em><%= note.created_at.stamp("July 4, 1776") %><em>
********STATUS********
$ rails g migration add_status_to_todos status:boolean
db/migrate/#####_add_status_to_todos
add_column :todos, :status, :boolean, :default => true
$ bundle exec rake db:migrate
views/todos/_form.html.erb
<div class="control-group">
<%= f.label :status, :class => 'control-label' %>
<div class="controls">
<%= radio_button("todo", "status", "true") %> Open<br>
<%= radio_button("todo", "status", "false") %> Closed
</div>
</div>
models/todo.rb
attr_accessible :status
views/todos/show.html.erb
<p>
<strong><%= model_class.human_attribute_name(:status) %>:</strong><br>
<% if @todo.status == true %>
Open
<% else %>
Completed
<% end %>
</p>
controllers/todos_controller.rb
def completed
@todos = Todo.find_all_by_status(false)
render :index
end
config/routes.rb
match '/completed' => 'todos#completed', :as => :completed
views/todos/index.html.erb
<th><%= model_class.human_attribute_name(:status) %></th>
<td>
<% if todo.status == true %>
Open
<% else %>
Completed
<% end %>
</td>
CHANGE "LINK 2" TO COMPLETE
app/layouts/application.html.erb
<li><%= link_to "Complete", completed_path %></li>
$ rails s
http://localhost:3000/
********ADVANCED BUT STARTING EASY********
CREATE STATIC PAGE. "about page"
config/routes.rb
match '/about' => 'welcome#about', :as => :our_cool_about_page
app/controllers/welcome_controller.rb
def about
end
app/views/welcome/about.html.erb
put whatever you want in here. It's you app!
CHANGE "LINK 3" TO ABOUT
app/views/layouts/application.html.erb
<li><%= link_to "About", our_cool_about_page_path %></li>
ADDING AN IMAGE
get an image from the interwebs
Place your image in "app/assets/images/"
app/views/welcome/index.html.erb
<div><%= image_tag('the-name-of-your-image.jpg') %></div>
GETTY FANCY WITH USER ACCOUNTS
stop the server "ctrl-c"
Gemfile
gem 'devise' # https://github.com/plataformatec/devise
$ bundle
$ rails g devise:install
# There will be some configuration here
app/config/environments/development.rb
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
app/views/layouts/application.html.erb
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
app/config/application.rb
config.assets.initialize_on_precompile = false
app/config/environments/production.rb
config.action_mailer.default_url_options = { :host => 'http://mywebsite.com' }
$ rails g devise User
$ bundle exec rake db:migrate
$ rails g devise:views
$ rails s
http://localhost:3000/
app/controllers/todos_controller.rb
before_filter :authenticate_user!
http://localhost:3000/todos
ADD SIGN IN AND SIGN UP LINKS
inside the sidebar area, replace Link1 & Link2. Delete Link3
app/views/layouts/application.rb
<li><%= link_to "Sign Up", new_user_registration_path %></li>
<li><%= link_to "Sign In", new_user_session_path %></li>
SIGN UP FOR AN ACCOUNT!
how do you log out?
UPDATE SIDEBAR
app/views/layouts/application.rb
<% if user_signed_in? %>
<li><%= link_to "Update Account", edit_registration_path(current_user) %></li>
<li><%= link_to "Sign Out", destroy_user_session_path, :method => :delete %></li>
<% else%>
<li><%= link_to "Sign Up", new_user_registration_path %></li>
<li><%= link_to "Sign In", new_user_session_path %></li>
<% end %>
REFRESH PAGE!
sign out then sign back in.
FIXING A BUG
app/helpers/application_helper.rb
def display_flash_message
[:notice, :success, :alert, :warning, :error].each do |message|
return content_tag(:div, flash[message], :class => message) if flash[message]
end unless flash.empty?
end
app/controllers/todos_controller.rb
def create
...
else
format.html {
flash[:alert] = 'Something went wrong trying to save the TODO'
render action: "new"
}
...
end
SIGN OUT & CREATE NEW ACCOUNT
http://localhost:3000/todos/
SCOPING TODOS
stop the server "ctrl-c"
app/models/user.rb
has_many :todos
app/models/todo.rb
belongs_to :user
$ rails g migration add_user_id_to_todos user_id:integer
$ bundle exec rake db:migrate
app/controllers/todos_controller.rb
replace all `Todo.` with `current_user.todos.`
NOTE: be sure the . is after the Todo if you "global find and replace". This ensures that the class name, and flash messages are untouched.
GETTING FANCY WITH HELPERS
app/helpers/application_helper.rb
def avatar(email, options = {})
require 'digest/md5'
hash = Digest::MD5.hexdigest(email)
image_src = url_for({:host => "www.gravatar.com/avatar/#{hash}", :d => 'mm'}.merge(options))
image_tag(image_src, :alt => 'Gravatar Image')
end
app/views/layouts/application.html.erb
<div class="pull-right">
<%= avatar(current_user.email) if user_signed_in? %>
</div>
<h3>Sidebar</h3>
MAKE AT LEAST 10 TODOS
TIME TO PAGINATE
stop the server "ctrl-c"
Gemfile
gem 'kaminari' #https://github.com/amatsuda/kaminari
$ bundle
app/controller/todos_controller.rb
def index
from: @todos = current_user.todos.find_all_by_status(true)
to: @todos = current_user.todos.where(:status => true).page(params[:page]).per(5)
def completed
from: @todos = current_user.todos.find_all_by_status(true)
to: @todos = current_user.todos.where(:status => false).page(params[:page]).per(5)
app/views/todos/index.html.erb
<%= paginate(@todos) %>
FIXING THE VIEWS
app/assets/application.css
span.page.current {
border-color: #DDDDDD;
border-style: solid;
border-width: 1px 1px 1px 0;
float: left;
line-height: 34px;
padding: 0 14px;
text-decoration: none;
}
reload page and see the fixed views
READY TO DEPLOY!!
stop the server "ctrl-c"
Signup at https://api.heroku.com/signup
Gemfile
group :development do
gem 'sqlite3' # <-- move this into here
gem 'heroku'
end
group :production do
gem 'pg'
gem 'thin'
end
$ bundle
$ git init .
$ git add .
$ git commit -m "Initial Commit"
$ heroku create --stack cedar
Enter in the credentials you signed up with.
The url of the app will be given to you after the app has been created.
$ git push heroku master
$ heroku run rake db:migrate