====
Based on guides.rubyonrails.org
Controller
is the C from MVC
Controller
Name
Preferable in plural:
ClientsController
Methods and
Actions
Normal ruby class the inherits
from ApplicationController
Ex /clients/new:
class
ClientsController < ApplicationController
def new
@client
= Client.new
end
end
Parameters
Rails doesn't make any
distinction between GET or POST parameters
# In the example:
def create
@client = Client.new(params[:client])
if @client.save
redirect_to @client
else
# This line overrides the default
rendering behavior, which
# would have been to render the
"create" view.
render "new"
end
end
# Values came from
<form accept-charset="UTF-8" action="/clients" method="post">
<input type="text" name="client[name]" value="Acme" />
<input type="text" name="client[phone]" value="12345" />
<input type="text" name="client[address][postcode]" value="12345" />
<input type="text" name="client[address][city]" value="Carrot City" />
</form>
JSON parameters
If working with
JSON, Rails convert automatically the parameters in parms hash.
Routing
parameters
Hash params always contains
:controller and :action keys
Strong
parameters
Action Controller parameters can
be used in Active Model mass assigments only after they pass through another
method(whitelisted). The params will be
chosen to be exposed.
Ex:
class
PeopleController < ActionController::Base
def
update
person =
current_account.people.find(params[:id])
person.update_attributes!(person_params)
redirect_to
person
end
private
def person_params
params.require(:person).permit(:name,
:age)
end
end
Session
Kinds of session:
ActionDispatch::Session::CookieStore
- Stores everything on the client.
ActionDispatch::Session::CacheStore
- Stores the data in the Rails cache.
ActionDispatch::Session::ActiveRecordStore
- Stores the data in a database using Active Record. (require
activerecord-session_store gem).
ActionDispatch::Session::MemCacheStore
- Stores the data in a memcached cluster
If you need a different session
storage mechanism, you can change it in the
config/initializers/session_store.rb file.
ex:
RomaMoneyRails::Application.config.session_store
:cookie_store, key: '_romaMoneyRails_session', domain: ".example.com"
#domain is
optional
CookieStore used for signing the
session data
Can be changed
in config/initializers/secret_token.rb:
EX, create a
random value:
require
'securerandom'
def
secure_token
token_file = Rails.root.join('.secret')
if File.exist?(token_file)
# Use the existing token.
File.read(token_file).chomp
else
# Generate a new token and store it in
token_file.
token = SecureRandom.hex(64)
File.write(token_file, token)
token
end
end
RomaMoneyRails::Application.config.secret_key_base
= secure_token
Accessing Session
def
current_user
@_current_user ||=
session[:current_user_id] &&
User.find_by(id:
session[:current_user_id])
end
def
create
if user =
User.authenticate(params[:username], params[:password])
# Save the user ID in the session so it
can be used in
# subsequent requests
session[:current_user_id] = user.id
redirect_to root_url
end
end
To
reset the intire session:
reset_session
Flash
Special
part of session that is cleared in each request. It will available only in the
next request.
Ex:
flash[:notice]
= "You have successfully logged out."
Cookie
To
store cookie is similar to Session
#
Remember the commenter's name.
cookies[:commenter_name] = @comment.author
Render xml and JSON data
class
UsersController < ApplicationController
def index
@users = User.all
respond_to do |format|
format.html # index.html.erb
format.xml { render xml: @users} # automatically invokes
@users.to_xml
format.json { render json: @users}
end
end
end
Render JSON with JavaScript
@user = User.first
respond_to do |format|
format.html {
redirect_to root_url }
format.js
end
Should have a
file js.erb with the same name of the action
Filter
Runs
before, after or "arround" the controller action
There
are different ways to access Filters, but these are the most known ones
before_action
Ex:
class
ApplicationController < ActionController::Base
before_action :require_login
private
def require_login
unless logged_in?
flash[:error] = "You must be logged
in to access this section"
redirect_to new_login_url # halts request
cycle
end
end
end
-
this will be run on every controller
Ex
of before_action for user_controller.rb
before_action
:signed_in_user,
only:
[:index, :edit, :update, :destroy, :change_to_this, :change_account,
:change_account_ajax]
before_action
:correct_user, only: [:edit, :update]
before_action
:admin_user, only: :destroy
Skiping
before for some methods
class
LoginsController < ApplicationController
skip_before_action :require_login, only:
[:new, :create]
end
after_action
After
is similar to before.
Has
access to response.
Can't
stop the action
arround_action
Run
the associated actions by yielding
Request Forgery Protection
First
step to protect destructive actions from forgery it prohibit GET requests(REST
already does this)
Request and Response objects
Request
Object
query_parameters
- sent as part of the query string
request_parameters
- sent as part of the post body
path_parameters
- parameters that were recognized by the routing as being part of the path
leading to this particular controller and action.
Response
Object
response.headers["Content-Type"]
= "application/pdf"
HTTP Authentications
Basic
Authentication
Very
simple
class
AdminsController < ApplicationController
http_basic_authenticate_with name:
"humbaba", password: "5baa61e4"
end
Digest
Authentication
only
requires using one method, authenticate_or_request_with_http_digest
Streaming and File Downloads
send_data
To
stream data to the client, use send_data:
Ex:
#Generate
a stream and send it
require
"prawn"
class
ClientsController < ApplicationController
# Generates a PDF document with information
on the client and
# returns it. The user will get the PDF as a
file download.
def download_pdf
client = Client.find(params[:id])
send_data generate_pdf(client),
filename:
"#{client.name}.pdf",
type: "application/pdf"
end
private
def generate_pdf(client)
Prawn::Document.new do
text client.name, align: :center
text "Address:
#{client.address}"
text "Email: #{client.email}"
end.render
end
end
send_file
To
send a file
class
ClientsController < ApplicationController
# Stream a file that has already been generated
and stored on disk.
def download_pdf
client = Client.find(params[:id])
send_file("#{Rails.root}/files/clients/#{client.id}.pdf",
filename:
"#{client.name}.pdf",
type:
"application/pdf") #default=application/octet-stream
end
end
It
read 4kb at time avoid loading the entire file to memory at once. It can be configure.
RESTFUL
download
First
include in config/initializers/mime_types.rb:
Mime::Type.register
"application/pdf", :pdf
class
ClientsController < ApplicationController
# The user can request to receive this
resource as HTML or PDF.
def show
@client = Client.find(params[:id])
respond_to do |format|
format.html
format.pdf { render pdf:
generate_pdf(@client) }
end
end
end
Log Filtering
Uses a
log file
Rescue
Useful
to send a specific exception to a page
ex:
class
ApplicationController < ActionController::Base
rescue_from ActiveRecord::RecordNotFound,
with: :record_not_found
private
def record_not_found
render text: "404 Not Found",
status: 404
end
end
Force ssl
In
config/environments/production.rb
#
Force all access to the app over SSL, use Strict-Transport-Security, and use
secure cookies.
config.force_ssl = true
Of for a specific action and
controller
class
DinnerController
force_ssl only: :cheeseburger
# or
force_ssl except: :cheeseburger
end
Nenhum comentário:
Postar um comentário