View basic
Lets start with generating a demo project called demo 3
rails new demo3
After generation completed, we could add post model with title and body fields
rails g scaffold post title:string body:text
<!DOCTYPE html>
<html>
<head>
<title>Demo3</title>
<%= stylesheet_link_tag :all %>
<%= javascript_include_tag :defaults %>
<%= csrf_meta_tag %>
</head>
<body>
<%= yield %>
</body>
</html>
go to views/layouts
yield basically appends all the rendering text from the views
go to the views/posts/index.html.erb file
<h1>Listing posts</h1>
<table>
<tr>
<th>Title</th>
<th>Body</th>
<th></th>
<th></th>
<th></th>
</tr>
<% @posts.each do |post| %>
<tr>
<td><%= post.title %></td>
<td><%= post.body %></td>
<td><%= link_to 'Show', post %></td>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
<td><%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New Post', new_post_path %>
Filters
before
after
around is executed both before and after an action is executed
private
def get_and_respond_with
@post = params[:id].present? ? Post.find( param )
yield
respond_with(@post)
end
Place private keyword to the end of your rails controller otherwise all the methods underneath it will become private members. Private members are there for
to not to serve a actions to the controllers
we can have a rendering login in before or after action, which needs to be
You can use
layout "my_layout"
to define a layout used all over the post controller which will search in the application folder
or simply create a new view under the application called “posts.html.erb” which will be automatically picked up by convention
or you can also define which template to use in an action
def index
@posts = Post.all
render :layout => 'juicy'
end
Partials
Add the following line under index.html.erb
<%= render 'category_list' %>
place a new layout view under posts called _category_list.html.erb
and place some html
Now navigate to /posts, you will see your extra html is rendered onto the page.
underscore ( “_” ) sign to the trick to indicate that it is a partial view.
Lets change the _category_list.html.erb file and add the following code
<h1> Category </h1>
<% categories.each do |c| %>
<li> <a href="#"> <%=c %> </a> </li>
<%end%>
undefined local variable or method `categories' for #<#<Class:0xa98d474>:0xa98ba98>
because we did not defined our categories variable we get an error. Lets define the variable in our render call
replace the render ‘category_list’ with
<%= render :partial => 'category_list' , :locals => { :categories => [ "test" , "test2" ] } %>
:locals is the data that we are passing into the partial view
and the only data is named “categories” with an array of values
we can also use layout to render the partial view
create a new file called _green_box.html.erb in posts folder and place the following html code
<div style="background-color:green">
<%= yield %>
</div>
and modify the render line with
<%= render :partial => 'category_list' , :locals => {:categories => [ "test" , "test2" ] } , :layout => 'green_box' %>
and refresh your posts page!
Helpers
bahadir@ubox:~/RubymineProjects/demo3$ rails g migration add_author
invoke active_record
create db/migrate/20110206174947_add_author.rb
Open up the add_author.rb
class AddAuthor < ActiveRecord::Migration
def self.up
add_column :posts , :author_first , :string
add_column :posts , :author_last , :string
end
def self.down
remove_column :posts , :author_first , :string
remove_column :posts , :author_last , :string
end
end
This is a migration script that will help us to create the author_first and author_last column when we migrate up ( self.up ) and remove them ( self.down ) if we want to migrate down
rake db:migrate
bahadir@ubox:~/RubymineProjects/demo3$ rake db:migrate
(in /home/bahadir/RubymineProjects/demo3)
== AddAuthor: migrating ======================================================
-- add_column(:posts, :author_first, :string)
-> 0.0008s
-- add_column(:posts, :author_last, :string)
-> 0.0005s
== AddAuthor: migrated (0.0016s) =============================================
Now go to _form.html.erb
<div class="field">
<%= f.label :author_first %><br />
<%= f.text_field :author_first %>
</div>
<div class="field">
<%= f.label :author_last %><br />
<%= f.text_field :author_last %>
</div>
and last thing to do is to add the fields to the show.html.erb file
<p>
<b>Author first:</b>
<%= @post.author_first %>
</p>
<p>
<b>Author last:</b>
<%= @post.author_last %>
</p>
Lets look at how we can use helpers
go to your index.html.erb and add the following line
<td><%= author_name(post) %></td>
and open up the helpers/posts_helper.rb
and define the following method
module PostsHelper
def author_name(post)
"#{post.author_first} #{post.author_last}"
end
end
Lets print out the date of the post as well. Open up helpers/application_helper.rb and add the pretty_date function
module ApplicationHelper
def pretty_date(date)
date.strftime("%B %d %Y")
end
end
now go back to index.html.erb file and change the author_name line by appending the date of the post
<td><%= author_name(post) %> - <%= pretty_date(post.created_at) %> </td>
Other View Engines - HAML
add the haml gem to the GEMFILE file
gem 'haml'
and
run the script
bundle install
and restart your server
create a new file called index.html.haml and add the following lines
%h1 Welcome
- @posts.each do |post|
- if (should_show?(post))
%h2= post.title
%i #{author_name(post)} - #{pretty_date(post.created_at)}
%hr
= link_to 'Show', post |
= link_to 'Edit' , edit_post_path(post)
= link_to 'Destroy', post, :confirm => 'Are you sure?' , :method => :delete
%br
= link_to 'New Post', new_post_path
Holy cow!
http://html2haml.heroku.com/
Holy cow #2
some more refactoring to the index.html.haml
%h1 Welcome
= render :partial => "category_list", :locals => { :categories => ["thing","thing2"] }
// you might not use as if you name the partial view as "post" but if you need to
// use the as parameter to pass in the collection item
= render :partial => 'post' , :collection => @posts , :as => :post
%br
= link_to "New Post", new_post_path
Create a new file called _post.html.haml and paste in
- if (should_show?(post))
%h2= post.title
%i #{author_name(post)} - #{pretty_date(post.created_at)}
%hr
= link_to "Show", post |
= link_to "Edit" , edit_post_path(post)
= link_to "Destroy", post, :confirm => "Are you sure?" , :method => :delete
ef55ebfe-f43f-4138-8434-ae7cdfdf6b94|0|.0