posted on Tuesday, June 29, 2010
This will increment "views" attribute of the post and save it to database, increment!(attribute, by=1):
@post.increment!(:views)
This will decrement "views" attribute of the post and save it to database, decrement!(attribute, by=1):
@post.decrement!(:views)
This will assign to attribute the boolean opposite of it:
@post.published # -> true
@post.toggle!(:published)
@post.published # -> false
class PostsController < ApplicationController
before_filter :find_post, :only => [:publish, :show]
def show
@post.increment!(:views)
end
private
def find_post
@post = Post.find(params[:id])
end
end
Reloading attributes from database, to get the latest values, reload(options = nil):
@post = user.posts.find(5)
user.posts.find(5).increment!(:views)
@post.views # -> 0
@post.reload
@post.views # -> 1
Reordering of already defined scope:
Post.scoped.collect {|p| p.id }
- 1
- 2
- 3
Post.scoped.reverse_order.collect {|p| p.id }
- 3
- 2
- 1
Continue reading
posted on Thursday, June 24, 2010
Simple fragment caching example:
<% cache do %>
Something here ...
<% end %>
Or if you want to specify action name and suffix of this cache block:
<% cache(:action => 'index', :action_suffix => 'all') do %>
Something here ...
<% end %>
Maybe it's not the best way to handle cached fragment names but i prefer using this kind of key:
<% cache('top#posts#') do %>
top posts block content ...
<% end %>
where 'top' is just a key of this cached fragment, but #posts# is used as identifier for the type of content, so for example we have 3 cached blocks, and they are not related to one controller or action:
When new post was created or deleted, instead of specifying expire_fragment for each cache key, you just add one line to your sweeper or observer or wherever you specify your expiring:
expire_fragment %r{#posts#}
And after that all cached blocks that related to posts are expired, its usefull when you have lots of fragments which are loaded from different controllers and actions and placed all over the website. The result of this is you'll never mess up with key names of your fragments, and will be sure that your cache is always up to date.
Continue readingposted on Tuesday, June 01, 2010
Here is some ways to manage html titles, keywords and description to have a seo friendly website:
Lazy way is to use an instance variable, which has a default value and you could override it in any controller's action:
controllers/posts.rb :
def index
@title = "Index title"
end
views/posts/index.html.erb :
<%=@title ||= "Default title"%>
If there is not too many pages on the website its better to use a helper with all titles and descriptions you need, to keep controllers clean from that kind of stuff. Also this method works good for those who want to have all their titles, descriptions etc. in one place to track it very easily.
helpers/application_helper.rb :
def title
titles = {
:blog => {
:index => "Index title",
:default => "Any other action title"
},
:users => {
:index => "Index title",
:show => "Show title",
:default => "Any other action title"
},
:default => "Default title"
}
c = params[:controller].to_sym
a = params[:action].to_sym
return titles[c] ? titles[c][a] ? titles[c][a] : titles[c][:default] : titles[:default]
end
views/layouts/application.html.erb :
<%=@title || title%>
Another one is content_for method, which probably is the best for 90% of websites:
views/layouts/application.html.erb :
<%= yield(:title) || "Default title" %>
views/posts/index.html.erb :
<%= title "Page title" %>
helpers/application_helper.rb :
def title html_title
content_for :title do
html_title
end
end
It's a good idea to move titles, description and keywords out from controllers because it is entirely a view responsibility even if you need them to be dynamicly made with user names or post tags.
Continue reading