Introduction to Web Architecture
View more presentations from cchamnap.
Web 2.0, Ruby, Rails, TDD, BDD,
rSpec, XMPP, BOSH, REST,
Javascript, Ajax, Google Maps API,
Google Gears API, CSS,
Java, C#, Social Network, RMagick, Nginx
/people/1?display=details
/people/1?display=summary
/people/1?display=details&format=xml
/people/1?display=summary&format=json
caches_action :index, :show, :cache_path => Proc.new { |c|
request_url = { :controller => c.params[:controller], :action => c.params[:action] }.merge(c.request.query_parameters)
c.url_for request_url
}
def set_default_response_format
response.headers['Content-type'] = 'application/xml; charset=utf-8' if params[:format].nil?
end
rescue_action_in_public. This method by default calls render_optional_error_file method to render a static page based on status code thrown. rescue_action_locally method by default will render details diagnostics from a controller action. Therefore, I just combine all of these methods into rescue_action_in_public and add some code to send mail.
def rescue_action_in_public(exception)
render_optional_error_file response_code_for_rescue(exception)
@template.instance_variable_set("@exception", exception)
@template.instance_variable_set("@rescues_path", RESCUES_TEMPLATE_PATH)
@template.instance_variable_set("@contents",
@template.render(:file => template_path_for_local_rescue(exception)))
# send mail to developers
mail = ExceptionNotifier.create_sent(@template)
mail.set_content_type("text/html")
ExceptionNotifier.deliver(mail)
end
class ExceptionNotifier < ActionMailer::Base
def sent(template)
@subject = 'Bug Reports'
@body["request"] = template.request
@body["response"] = template.response
@body["exception"] = template.instance_variable_get("@exception")
@body["rescues_path"] = template.instance_variable_get("@rescues_path")
@recipients = ['chamnapchhorn@gmail.com', 'ungsophy@gmail.com']
@from = 'noreply@gmail.com'
@headers = {}
end
end
<h1>
<%=h @exception.class.to_s %>
<% if @request.parameters['controller'] %>
in <%=h @request.parameters['controller'].humanize %>Controller<% if @request.parameters['action'] %>#<%=h @request.parameters['action'] %><% end %>
<% end %>
</h1>
<pre><%=h @exception.clean_message %></pre>
<%= render :file => @rescues_path["rescues/_trace.erb"] %>
<%= render :file => @rescues_path["rescues/_request_and_response.erb"], :locals => { :request => @request, :response => @response } %>
rescue_action and rescue_action_in_public) that you would need to override based on your needs. By default, these two methods do the best job to handle exception both in development and production mode. rescue_action method will be called with an exception parameter that raises inside an action method. rescue_action_in_public method, however, is used for public exception handling (for requests answering false to local_request?). local_request? method tells which rescue_*** method to call.
class PostsController < ApplicationController
def rescue_action_in_public(exception)
case(exception)
when ActiveRecord::RecordNotFound then render :file => '/bad_record'
when NoMethodError then render :file => '/no_method'
else render :file => '/error'
end
end
end
class PostsController < ApplicationController
# Declare exception to handler methods
rescue_from ActiveRecord::RecordNotFound, :with => :bad_record
rescue_from NoMethodError, :with => :show_error
def bad_record; render :file => '/bad_record'; end
def show_error(exception); render :text => exception.message; end
end
var popupWin = null;
function openPopup() {
var url = "popup.htm";
popupWin = open( "", "popupWin", "width=500,height=400" );
if( !popupWin || popupWin.closed || !popupWin.doSomething ) {
popupWin = window.open( url, "popupWin", "width=500,height=400" );
} else {
popupWin.focus();
}
}
function doSomething() {
openPopup();
popupWin.doSomething();
}
self.focus();
function doSomething() {
alert("I'm doing something");
}
<script type="text/javascript">if(top == self) { document.write(""); } else { top.location.href = "http://www.yahoo.com"; }</script>
// Create a new popup window
var popupWin = window.open(url, "popupWin");
// To call functions defined in the popup:
popupWin.doSomething();
window.opener.doSomethingOnParent();
def login
@status = "something"
end
#view
<html><head></head>
<body onload="window.opener.handleOpenIDResponse('" + @status + "');window.close();">
</body>
</html>
class CreateProjectsProgrammers < ActiveRecord::Migration
def self.up
create_table :projects_programmers, :id => false do |t|
t.column :project_id, :integer, :null => false
t.column :programmer_id, :integer, :null => false
end
end
def self.down
drop_table :projects_programmers
end
end
class Programmer < ActiveRecord::Base
has_and_belongs_to_many :projects # foreign keys in the join table
end
class Project < ActiveRecord::Base
has_and_belongs_to_many :programmers # foreign keys in the join table
end
push_with_attributes to do this. However, push_with_attributes has been deprecated in favor of a far more powerful technique, where regular Active Record models are used as join tables (remember that with habtm, the join table is not an Active Record object).has_many :through once you need to add additional columns.
class Article < ActiveRecord::Base
has_many :readings
end
class User < ActiveRecord::Base
has_many :readings
end
class Reading < ActiveRecord::Base
belongs_to :article
belongs_to :user
end
reading = Reading.new
reading.rating = params[:rating]
reading.read_at = Time.now
reading.article = current_article
reading.user = session[:user]
reading.save
class Article < ActiveRecord::Base
has_many :readings
has_many :users, :through => :readings
end
class Reading < ActiveRecord::Base
belongs_to :article
belongs_to :user
end
class User < ActiveRecord::Base
has_many :readings
has_many :articles, :through => :readings
end
readers = an_article.users
articles = a_reader.articles
user.readings.create(:read_at => Time.now,
:rating => params[:rating],
:article => Article.new)
user = User.authenticate(params[:user_name], params[:password])
if user
session[:current_user] = user.attributes
else
flash[:notice] = "Email and password do not match."
redirect_to :controller => "login"
end
class ApplicationController < ActionController::Base
before_filter :get_current_user
private
def get_current_user
@current_user = User.find_by_id(session[:user_id])
end
end