Use LEFT and RIGHT arrow keys to navigate between flashcards;
Use UP and DOWN arrow keys to flip the card;
H to show hint;
A reads text to speech;
948 Cards in this Set
- Front
- Back
The contoller should hand off heavy code to...
|
the model
|
|
How many ways can controller create http responses?
|
3 - render, redirect, head
|
|
By default, controllers in Rails automatically render ...
|
views with names that correspond to valid routes.
e.g. resources :books -> /books/ -> index |
|
Will this work to render an index page?
def index @books = Book.all end |
Yes we have convention over configuration, in that there is no explicit render at the end of this index action. The rule is that if you do not explicitly render something by the end of the controller action, rails will look for the action_name.html.erb template in the controllers view path and then render that,
|
|
If you want to see the exact results of a call to render without needing to inspect it in a browser, you can call
..... |
render_to_string
|
|
What does response 200 ok mean?
|
the request was successful
|
|
How do you change the http resonse for a request?
|
set the :status options on render to change this response
|
|
How do you render the view that corresponds to a different action within the same template?
|
call render with the views name
def update if @book.update_attributes(params[:book]) else render "edit" end |
|
Render accepts symbols or strings
|
both
render "edit" and render :edit both work |
|
Do you need to use render with the :action option
render :action => "edit" |
NO - not in rails 3 - the string or symbol is enough
|
|
Does render a specified action run the code in the controller? action in the controller.
|
No specified action is used to determine which view to render, but Rails does not run any of the code for that
|
|
How to render an Action’s Template from Another Controller
|
You can also do that with render, which accepts the full path (relative to app/views) of the template to render.
render 'products/show' same as render :template => 'books/edit' |
|
Rendering an Arbitrary File e.g. a view that’s entirely outside of your application (perhaps you’re sharing views between two Rails applications)
|
render "/u/apps/warehouse_app/current/app/views/products/show"
same as the file option :file => "/u/apps/warehouse_app/current/app/views/products/show" |
|
What does this do?
render :inline => "<% products.each do |p| %><p><%= p.name %><p><% end %>" |
The render method can do without a view completely, if you’re willing to use the :inline option to supply ERB as part of the method call.
here is seldom any good reason to use this optio |
|
How to render javascript-based page updates inline in your controller?
|
render :update do |page| page.replace_html 'warning', "Invalid options supplied" end
use rjs instead |
|
How to send plain text – with no markup at all – back to the browser
|
render :text => "OK"
useful most useful when you’re responding to AJAX or web service requests that are expecting something other than proper HTML.y |
|
How to render in json
|
render :json => @product
|
|
Do you need need to call to_json on the object that you want to render. If you use the :json option
|
no - called auto by render :json
|
|
How to render xml
|
render :xml => @product
|
|
Where does Rails look to fnd the current layout,
|
Rails first looks for a file in app/views/layouts with the same base name as the controller.
|
|
How to override the automatic layout conventions in your controllers
|
class ProductsController < ApplicationController
layout "inventory" #... end |
|
How to To assign a specific layout for the entire application,
|
class ApplicationController < ActionController::Base l
ayout "main" #... end |
|
How to dynamically choose a layout at runtime
|
class ProductsController < ApplicationController
layout :products_layout def show @product = Product.find(params[:id]) end private def products_layout @current_user.special? ? "special" : "products" end end |
|
`how to pass layouts either a method name or an array of method names which correspond to method names within the controller to inclue / exclude
|
:only and :except options
layout "product", :except => [:index, :rss] |
|
Rails will start the rendering proces does this stop the rest of the code in the action from running
|
No - thus if another render is called “Can only render or redirect once per action” is thrown
|
|
“Can only render or redirect once per action” - is this ever thrown due to the implicit render?
|
no - it detects if render has already been called
|
|
best practice conditional rendering (1 condition, otherwise default)
|
def show
@book = Book.find(params[:id]) if @book.special? render :action => "special_show" end end |
|
What does the redirect_to method do
|
it tells the browser to send a new request for a different UR
|
|
special redirect that sends the user back to the page they just came from:
|
redirect_to :back
|
|
HTTP status code .... when you call redirect_to. I
|
302 (temporary redirect)
|
|
what is the speed issue with redirect_to?
|
it requires a round trip to the browser
added latency |
|
Idea to overcome added latency when redirecting
|
Prepare the passed variables and render instead
def show @book = Book.find_by_id(params[:id]) if @book.nil? @books = Book.all render "index", :alert => 'Your book was not found!' end end |
|
how to link to js files
|
javascript_include_tag
|
|
where does javascript_include_tag look by default
|
public/javascripts f
|
|
How to To include public/javascripts/main.js and public/javascripts/columns.js:
|
<%= javascript_include_tag "main", "columns" %>
|
|
what is the speed issue with redirect_to?
|
it requires a round trip to the browser
added latency |
|
Idea to overcome added latency when redirecting
|
Prepare the passed variables and render instead
def show @book = Book.find_by_id(params[:id]) if @book.nil? @books = Book.all render "index", :alert => 'Your book was not found!' end end |
|
how to link to js files
|
javascript_include_tag
|
|
where does javascript_include_tag look by default
|
public/javascripts f
|
|
How to To include public/javascripts/main.js and public/javascripts/columns.js:
|
<%= javascript_include_tag "main", "columns" %>
|
|
How to load all js files, including those in subfolders of public/javascripts as well:
|
<%= javascript_include_tag :all, :recursive => true %>
|
|
how to combine js files into one (faster)
|
<%= javascript_include_tag "main", "columns", :cache => true %>
|
|
javascript_..._tag
stylesheet_..._tag |
include
link |
|
where does stylseheet include tag look by default
|
public/stylesheets
|
|
do you need to specify .css / .js with their include/link tags
|
no - just a string of their file name - e.g. main.css "main"
|
|
what is the default media type of stylehseet_link_tag
|
media="screen"
|
|
how to specify a media type with stylesheet-Includ_tag
|
%= stylesheet_link_tag "main_print", :media => "print" %>
|
|
how to inks every CSS file in public/stylesheets:
|
<%= stylesheet_link_tag :all %>
, :recursive => true for subfolders |
|
how to link to an image in public/images
|
<%= image_tag "header.png" %>
default dir is public/iages |
|
for image_tags do you need to specify the extension
|
yes - new to rails 3 - error if no extension given
|
|
How to add html options with image_tag (e.g. for height)
|
<%= image_tag "icons/delete.gif", {:height => 45} %>
must be in a prop => value hash |
|
with image_tag how do you supply an alternate image to show on mouseover:
|
<%= image_tag "home.gif", :onmouseover => "menu/home_highlight.gif" %>
|
|
if you do not specify an explicit alt tag, image_tag defaults to ..
|
the file name of the file
override with <%= image_tag "home.gif", :alt => "My Lovely Home" %> |
|
whats a handy way to specify an images size with image_tag
|
<%= image_tag "home.gif", :size => "50x20" %>
|
|
how to specify class or id of an image_tag
|
<%= image_tag "home.gif", :alt => "Go Home", :id => "HomeImage", :class => 'nav_bar' %>
|
|
how to inclue a HTML 5 <video> in rails
|
<%= video_tag "movie.ogg" %>
relative to the public/videos |
|
does the video_tag have the specify the :size => "#{width}x#{height} like image_tag
|
yes it sure does
|
|
starts playing the video on page load. viedo_tag
|
# :autoplay => true,
|
|
loops the video once it gets to the end viedo_tag
|
:loop => true,
|
|
image to put in place of the video before it starts playing. viedo_tag
|
:poster => 'image_name.png', provides an
|
|
provides browser supplied controls for the user to interact with the video
|
:controls => true
|
|
link to an mp3 (
|
<%= audio_tag "music.mp3" %>
|
|
where audio_tag looks for mp3s
|
public/audios.
|
|
Within the context of a layout, yield identifies?
|
a section where content from the view should be inserted.
<body> <%= yield %> </body> |
|
multiple yielding regions: how
|
<%= yield :head %> as well as regular <%= yield %> elswhere (referred to as unnamed yeild)
now use a <% content_for :head do %> <title>A simple page</title> <% end %> |
|
You only use content_for to insert content in
|
named yields
|
|
content_for is useful for
|
load page-specific javascript or css files into the header of an otherwise generic layout.
|
|
how to partial as part of a view
|
<%= render "menu" %>
This will render a file named _menu.html.erb at that point within the view being rendered. |
|
partials could contain content that is
|
shared among many pages in your application.
|
|
For content that is shared among all pages in your application, you can use partials directly from
|
layouts.
|
|
How to use partial layouts
|
<%= render "link_area", :layout => "graybar" %>
render it using the layout _graybar.html.erb. |
|
syntax for passing variables to partials
|
:locals => { :zone => @zone }
view has @zone partial gets zone (e.g. %= form_for(zone) do |f| %> <p> ) |
|
Every partial also has a local variable with the same name as the.....
|
partial (minus the underscore).
|
|
what does this doe <%= render :partial => "customer", :object => @new_customer %>
_customer partial |
Within the customer partial, the customer variable will refer to @new_customer from the parent view.
[since every partial has a local var with sme name as partial] |
|
If you have an instance of a model to render into a partial, you can use a shorthand syntax:
|
<%= render @customer %>
will use _customer.html.erb to render it and will pass the local variable customer into the partial |
|
how to set it so the partial will be inserted once for each member in the collection:
|
<%= render :partial => "product", :collection => @products %>
|
|
What should you be aware of when rendering collections of partials
<%= render :partial => "product", :collection => @products %> |
the individual instances of the partial have access to the member of the collection being rendered via a variable named after the partial.
he partial is _product, and within the _product partial, you can refer to product to get the instance that is being rendered. |
|
Shorthand for rendering a collection of partials
|
<%= render @products %>
Rails determines the name of the partial to use by looking at the model name in the collection. |
|
how to render aheterogeneous collection of cartials
|
<%= render [customer1, employee1, customer2, employee2] %>
In this case, Rails will use the customer or employee partials as appropriate for each member of the collection. |
|
use a custom local variable name within the partial, specify the
|
:as option
With this change, you can access an instance of the @products collection as the item local variable within the partial. |
|
How to pass it variables to the partial which are only defined in the render call
|
:locals => {:title => "Products Page"}
|
|
Rails also makes a .... variable available within a partial called by the collection
tell you how many times the partial has been rendered |
counter
For example, if you’re rendering @products, within the partial you can refer to product_counter |
|
how to specify a second partial to be rendered between instances of the main partial
|
<%= render @products, :spacer_template => "product_ruler" %>
|
|
howt o override sections of the main layout (application.html) in layout/news
|
app layout <style type="text/css"><%= yield :stylesheets %></style>
layouts/news <% content_for :stylesheets do %> #top_menu {display: none} <% end %> |
|
routing determines which....... to use for a request then
|
controller
|
|
Once your controller receives a request via routing it is responsible for ......
|
making sense of the request and producing the appropriate output.
|
|
what happens once the routing determines which controller and action to run
|
Rails creates an instance of that controller and runs the method with the same name as the action.
|
|
what view will be rendered here and what does this show:
def new end |
Rails will by default render the new.html.erb view unless the action says otherwise
|
|
regular controllers inherit from
|
ApplicationController
|
|
ApplicationController inherits from
|
ActionController::Base,
|
|
Only .... controller methods are callable as actions
|
public -> thus lower the visibility of methods not intended to be actions (like filters) by putting under private
|
|
What are the two kinds of parameters possible in a web application.
|
1 query string parameters
2 POST data |
|
what is query string parameters
|
parameters that are sent as part of the URL, called query string parameters. The query string is everything after “?” in the URL.
|
|
what is POST data
|
comes from an HTML form which has been filled in by the user. It’s called POST data because it can only be sent as part of an HTTP POST request.
|
|
Does Rails make any distinction between query string parameters and POST parameters?
|
no - both are available in the params hash in your controller:
|
|
how does this get translated into params in a controller:
/clients?status=activated |
params[:status] = "activated"
thus use logic like if params[:status] == "activated" |
|
index is a HTTP GET request thus it would use what kind of params
|
query string params - e.g. /clients?status=activated
|
|
what is the url submitted when there is a boatload of POST data?
|
"/clients", and the data is sent as part of the request body, thus hidden (unlike query params)
|
|
how to send an array of values to the controller
|
append an empty pair of square brackets “[]” to the key name:
GET /clients?ids[]=1&ids[]=2&ids[]=3 |
|
how is this encoded irl
GET /clients?ids[]=1&ids[]=2&ids[]=3 |
“/clients?ids%5b%5d=1&ids%5b%5d=2&ids%5b%5d=3” as “[” and “]” are not allowed in URLs. Most
don't worry though - rails does this automatically |
|
parameter values are always .....
|
strings;
|
|
Does Rails make any attempt to guess or cast the type of params?
|
No - you must do this yourself
|
|
what is params[:ids] here?
ids[]=1&ids[]=2&ids[]=3 |
The value of params[:ids] will now be ["1", "2", "3"]
|
|
how do you send a hash of params?
|
include the key name inside the brackets:
<input type="text" name="client[name]" value="Acme" /> <input type="text" name="client[phone]" value="12345" /> |
|
<input type="text" name="client[name]" value="Acme" /> <input type="text" name="client[phone]" value="12345" />
what is params[:client] |
, the value of params[:client] will be {"name" => “Acme”, “phone” => “12345”}
|
|
what is the value of params[:client] here?
<input type="text" name="client[address][postcode]" value="12345" /> |
{ “address” => {"postcode" => “12345”}}
see how a hash is nested |
|
what will the params hash always contain?
|
the :controller and :action keys
|
|
is the best way to access the controller / action name through the the :controller and :action params keys?
|
no use the methods controller_name and action_name instead
|
|
are any other params defined by the routing available - give an example
|
yes - e.g. params[:id] might be available
|
|
how to add a route which captures the :status paramater or a url
|
map.connect "/clients/:status", :controller => "clients", :action => "index"
|
|
Given:
map.connect "/clients/:status", :controller => "clients", :action => "index" when a user opens the URL /clients/active, params[:status] will be set to |
“active”
|
|
what is the consequence of this route (look at :foo)
map.connect "/clients/:status", :controller => "clients", :action => "index", :foo => "bar" |
params[:foo] will also be set to “bar” just like it was passed in the query string.
|
|
how to set global default parameters that will be used when generating URLs
|
def default_url_options(options) {:locale => I18n.locale}
end used in controllers (individual or ApplicationController) |
|
what are sessions used for
|
store small amounts of data that will be persisted between requests.
|
|
The session is only available in the ... and ...
|
controller and the view
|
|
where does this session storage mechanism store it's data?
CookieStore |
Stores everything on the client.
|
|
where does this session storage mechanism store it's data?
DRbStore |
Stores the data on a DRb server.
|
|
where does this session storage mechanism store it's data?
DRbStore |
Stores the data in a memcache.
|
|
where does this session storage mechanism store it's data?
ActiveRecordStore |
Stores the session data in a database using Active Record.
|
|
Does Rails allow you to pass the session ID in the URL
|
No - this is too insecure.
|
|
All session stores use a ... to store a unique ID for each session
|
cookie (since passing session id in url is too insecure)
|
|
For 3/4 session stores the ID cookie is used to ...
|
look up the session data on the server, e.g. in a database table.
|
|
What is the one exception to looking up session data on the server
|
The CookieStore – which stores all session data in the cookie itself (the ID is still available to you if you need it)
|
|
What is the default and recommended session store
|
the CookieStore
|
|
2 advantages of CookieStore
|
very lightweight and it requires zero setup in a new application in order to use the session.
|
|
cookie data is .... signed to make it tamper-proof
|
cryptographically
|
|
cryptographically signed means?
|
not encrypted, so anyone with access to it can read its contents but not edit it (Rails will not accept it if it has been edited).
|
|
CookieStore can store around ... of data
|
4kb
|
|
How to change session storage mechanism
|
config/initializers/session_store.rb
# ActionController::Base.session_store = :active_record_store |
|
What is your your secret key for?
|
verifying cookie session data integrity.
|
|
why should secret be at least 30 characters all random?
|
you'll be exposed to dictionary attacks.
|
|
why stake care when changing the secret when using the CookieStore ?
|
It will invalidate all existing sessions.
|
|
How are session values stored
|
Session values are stored using key/value pairs like a hash:
User.find(session[:current_user_id]) |
|
Do you ever need to disable sessions to speed up an app?
|
no. Sessions are lazily loaded. If you don’t access sessions in your action’s code, they will not be loaded.
|
|
How to store something in the session?
|
assign it to the key like a hash:
session[:current_user_id] = user.id |
|
How to remove something from the session?
|
assign that key to be nil:
session[:current_user_id] = nil |
|
Why is the flash a special part of the session which is cleared with each request
|
cleared with each request.
his means that values stored there will only be available in the next request, which is useful for storing error messages etc. |
|
Where is it conventional to display eventual errors or notices from the flash?
|
Application layout
<% if flash[:notice] %> <p class="notice"><%= flash[:notice] %></p> <% end %> <% if flash[:error] %> <p class="error"> <%= flash[:error] %></p> <% end %> |
|
what are the two conventional types of flash?
|
flash[:error]
flash[:notice] |
|
How do you get a flash value to be carried over to another request,
|
use the keep method:
# Let's say this action corresponds to root_url, but you want # all requests here to be redirected to UsersController#index. # If an action sets the flash and redirects here, the values # would normally be lost when another redirect happens, but you # can use 'keep' to make it persist for another request. def index # Will persist all flash values. flash.keep |
|
How to keep only some kind of flash value.
|
# flash.keep(:notice)
|
|
How to access flash values in the same request (e.g. if the create action fails to save a resource and you render the new template directly, that’s not going to result in a new request)
|
if @client.save
# ... else flash.now[:error] = "Could not save client" render :action => "new" |
|
namespace :backups do
desc "backup db from heroku and send to S3" task :backup => :environment do how to run this rake task |
rake backups:backup
namespace:task is the format |
|
task :the_task do
p "one" end task :the_task do p "two" end rake the_task shows what? what does this show? |
Rake::Task[:the_task].invoke
# >> "one" # >> "two" rake tasks append behaviour! |
|
How to Auto-fill the commenter's name if it has been stored in a cookie ?
|
@comment = Comment.new(:name => cookies[:commenter_name])
|
|
How to remember the commenter's name in a cookie?
|
cookies[:commenter_name] = @comment.name
|
|
How to delete cookie for the commenter's name cookie, if any
|
cookies.delete(:commenter_name)
|
|
What is the difference between clearing session and cookie values?
|
session values are set to nil
coookies use cookies.delete(:key) |
|
What are filters?
|
methods that are run before, after or “around” a controller action.
|
|
How to run a filter on every controller in your application.
|
set a filter on ApplicationController
|
|
how to define a before filter
|
class ApplicationController < ActionController::Base
before_filter :require_login private def require_login ...... |
|
What does this do:
!!current_user |
converts something to true or false (instead of giving a user object or nil here)
|
|
Give an example of a basic reqire_login filter which halts the request cycle if not logged in
|
def require_login
unless logged_in? redirect_to new_login_url # halts request cycle end end #logged in can be defined further in the contorller private methods |
|
If a before filter renders or redirects, the action will .....
|
not run
|
|
If there are additional filters scheduled to run after a filter which renderes or redirects they are ...
|
also cancelled.
|
|
How to prevent a filter from running before particular actions (assuming the filter is in application controller)
|
class LoginsController < ApplicationController
skip_before_filter :require_login, :only => [:new, :create] #note how the code is within the logins controller (even though the filter is in original backup) |
|
what filter runs once a controller action has already run
|
after_filter
|
|
what filter is run both before and after a controller filter
|
around_filter
around_filter :catch_exceptions |
|
Two other ways to use controller fiters
|
1. Use a class
before_filter LoginFilter 2 Use a block before_filter do |controller| redirect_to new_login_url unless controller.send(:logged_in?) end #send is used here since logged_in? is a private method |
|
When to use a class for a filter?
|
Cases that are more complex and can not be implemented in a readable and reusable way using the two other methods.
|
|
What does a filter class look like?
|
class LoginFilter
def self.filter(controller) unless controller.send(:logged_in?) controller.flash[:error] = "You must be logged in" controller.redirect_to controller.new_login_url end end #note the use of the controller object |
|
What do verifications do?
|
make sure certain criteria are met in order for a controller or action to run.
|
|
Controller Verification can specify that a certain key (or several keys in the form of an array) is present in the ...
hashes |
1 params hash
2 session hash 3 flash hashe |
|
Controller Verification can also specify that a certain .... method was used
|
HTTP METHOD
|
|
What default action does controlelr verification take when its criteria are not met?
|
render a 400 Bad Request response, but you can customize this by specifying a redirect URL or rendering something else
# in a controller verify :params => [:username, :password], :render => {:action => "new"} |
|
How to add a flash to a verification
|
verify :params => [:username, :password],
:add_flash => { :error => "Username and password required to log in" } |
|
verifications are by default used for .... action in the contoller
|
verifications are used for every action
|
|
how to specify a verification should only run for certain actions
|
verify ..., :only => :create
#except also works too... like filters |
|
how to view the history of a file in git
|
gitk service_provider.rb
|
|
how to troubleshoot errors with migrating down?
|
look for spelling inconsistencies between up and down methods
check for premptive table downs (on migration files despite previous ones requiring) go into sql and desc tables |
|
First step to avoid Cross-site request forgery
|
make sure all “destructive” actions (create, update and destroy) can only be accessed with non-GET requests. If you’re following RESTful conventions you’re already doing this.
|
|
How to avoid Cross-site request forgery given that some attacks can come as a non-GET request?
|
request forgery protection
add a non-guessable token which is only known to your server to each request. This way, if a request comes in without the proper token, it will be denied access. |
|
How to active cross site request forgery protect
|
Rails adds this token to every form that’s generated using the form helpers, so most of the time you don’t have to worry about it unless you’re writing a form manually
|
|
Given that rails auto adds forgery protection to forms, how do these forms look?
|
<form action="/users/1" method="post"> <
input type="hidden" value="67250ab105eb5ad10851c00a5621854a23af5489" name="authenticity_token"/> <!-- fields --> </form> |
|
what method is used to manually protect from forgery?
|
form_authenticity_token
|
|
what two speciall accessor methods does every controller have?
|
methods pointing to the request and the response objects associated with the request cycle that is currently in execution.
|
|
request method contains an instance of ....
|
AbstractRequest
|
|
response method contains
|
response object representing what is going to be sent back to the client.
|
|
how to filter out sensitive information from the log.
|
filter_parameter_logging method
|
|
How to use filter_parameter_logging method
|
class ApplicationController < ActionController::Base filter_parameter_logging :password end
|
|
How does the filter_parameter_logging method work?
|
It works by replacing certain values in the params hash with “[FILTERED]” as they are written to the log
|
|
f the user follows a link to a resource that no longer exists in the database, Active Record will throw the ...
|
ActiveRecord::RecordNotFound exception.
|
|
“404 Not Found” is shown if ... or ...
|
1 if there was a routing error or
2 a record could not be found. |
|
By default a production application will render either a ... or a ... error message
|
404 or a 500
|
|
How to rescue from certain errors in a controller
|
rescue_from ActiveRecord::RecordNotFound, :with => :record_not_found
private def record_not_found render :text => "404 Not Found", :status => 404 end |
|
If you want to be hardcore about exceptions what could you do?
|
you could create custom exception classes that will be thrown
|
|
How to raise a custom exception
|
Have a filter with a custom method in a controller
that custome method should raise the new exception e.g. def check_authorization raise User::NotAuthorized unless current_user.admin? end |
|
Why is It is not recommended that you stream static files through Rails?
|
you can instead keep them in a public folder on your web server. It is much more efficient to let the user download the file directly using Apache or another web server, keeping the request from unnecessarily going through the whole Rails stack
|
|
What is the (unrecommended) way to send files that already exist on disk?
|
send_file("#{Rails.root}/files/clients/#{client.id}.pdf", :filename => "#{client.name}.pdf", :type => "application/pdf")
#done within a method in the controller e.g. def download_pdf |
|
Why is send_data not restful?
|
having separate actions for file downloads is usually not necessary. In REST terminology, the PDF file from the example above can be considered just another representation of the client resource
|
|
What is the sleek way of doing “RESTful downloads”?
|
def show
@client = Client.find(params[:id]) respond_to do |format| format.html format.pdf { render :pdf => generate_pdf(@client) } end #remember to add the PDF MIME TYPE |
|
Where are mime types kept in rails?
|
config/initializers/mime_types.rb:
|
|
How to add a mime type in config/initializers/mime_types.rb:
|
Mime::Type.register "application/pdf", :pdf
|
|
Are Configuration files (such as initializzers) not reloaded on each request?
|
NO - have to restart the server in order for their changes to take effect.
|
|
When something fishy is going wrong using a gem method what should you try?
|
see if the gem has been updated - it's possible an old version may be play
|
|
How to get the url requested?
|
Request.url
|
|
How to get the method used for the request?
|
Request.method
|
|
How to get the The query string part of the URL, i.e., everything after “?”.
|
Request.query_string
|
|
How to get yhe IP address of the client?
|
Request.remote_ip
|
|
What three accessors does the request object have that give you access to paramets?
|
query_parameters hash
request_parameters hash path_parameters hash |
|
Some of these accessor methods for the response object also have ....
|
setters, allowing you to change their values.
|
|
How to access the string of data being sent back to the client. This is most often HTML?
|
Response.body
|
|
How to access the HTTP status code for the response, like 200 for a successful request or 404 for file not found.
|
Response.status
|
|
How to access the URL the client is being redirected to, if any.
|
Response.location
|
|
How to access the content type of the response.
|
Response.content_type
|
|
How to use Rail's built-in authentication?
|
authenticate_or_request_with_http_basic.
[not recommended as there it passes password unencrypted over http (though not https) |
|
What would go inside a method which authenticated using authenticate_or_request_with_http_basic ?
|
authenticate_or_request_with_http_basic do
|username, password| username == USERNAME && Digest::SHA1.hexdigest(password) == PASSWORD end |
|
If you have a controller with filters and private methods you'd like to apply to other controllers how do you inherit?
|
create namespaced controllers that inherit from AdminController
|
|
What is superior to authenticate_or_request_with_http_basic.
|
authenticate_or_request_with_http_digest
password is encrypted |
|
give an example of authentication using
authenticate_or_request_with_http_digest |
authenticate_or_request_with_http_digest do
|username| USERS[username] #top of controller USERS = { "lifo" => "world" } end |
|
When a form_tag is called on it's own what action and HTTP method is used?
<% form_tag do %> #contents <% end %> |
action -> current page
method -> post |
|
what HTTP mehod should you use for search forms?
|
GET -> since users need to be able to bookmark specific searches and get back
|
|
how to specify a get method and the search_path url in a form?
|
<%= form_tag(search_path, :method => "get" do %>
label_tag text_field_tag submit_tag |
|
what shortcut can you use for specifying methods to use in a form?
|
named routes - e.g. form_tag(search_path)
|
|
for every form input an ...... is generated from it's name
and this is useful for ....... |
Every form input has an ID attribute generated from its name - useful for CSS/JS
|
|
what's wrong with this:
form_tag(:controller => "people", :action => "search", :method => "get", :class => "nifty_form") compared to: form_tag({:controller => "people", :action => "search"}, :method => "get", :class => "nifty_form") |
Here you wanted to pass two hashes, but the Ruby interpreter sees only one hash, so Rails will construct a URL with extraneous parameters
# => <form action="/people/search?method=get&class=nifty_form" method="post"> |
|
if a form helper has unexpected output what should you do?
|
make sure that you have delimited the hash parameters properly.
|
|
if the form contains
<%= text_field_tag(:query) %> then the controller code can access the input with |
params[:query]
|
|
These basic helpers, with names ending in _tag such as text_field_tag, check_box_tag take as a first parameter...
|
the name of the input (which is assigned as the key in the params)
|
|
how to specify a text_field_tag for surname
|
<%= text_field_tag(:surname) %>
|
|
How do you specify which value a check box tag will submit when a checkbox is ticked?
|
the second param
<%= check_box_tag(:pet_cat, "I own a cat") %> #if ticked i own a cat is submitted |
|
How to access this check boxes details in the controller?
<%= check_box_tag(:pet_cat, "I own a cat") %> |
params[:pet_dog]
|
|
Difference between checkboxes and radio buttons?
|
Radio boxes are sets of options which are mutually exclusive, where users can pick multiple checkboxes
|
|
Why should you always use labels for each checkbox and radio button?
|
They associate text with a specific option and provide a larger clickable region.
|
|
How do you specify that two radio buttons be mutually exclusive? ie choose one of the other
|
Give both the same name (first param)
<%= radio_button_tag(:age, "adult") %> <%= radio_button_tag(:age, "child") %> |
|
How to have a label for a radio_button differ from the value passed?
|
<%= radio_button_tag(:age, "child") %> <%= label_tag(:age_child, "I am younger than 21") %>
#I am younger than displayed #child passed |
|
form helper for passwords
|
password_field_tag(:password)
|
|
how to pass hidden options via a form
|
<%= hidden_field_tag(:parent_id, "5") %>
|
|
Values inside hidden fields can be changed with ....
|
JavaScript.
|
|
how to stop passwords showing in logs?
|
filter_parameter_logging(:password)
#assumes password input field #place this in applicationcontroller |
|
Can the _tag helpers be used for created and editing a model?
|
Yes - but overly verbose - one big problem is that the defaults are not filled in
|
|
Model objects helper first arg?
|
An instance variable (usually name of model)
E.g. <%= text_field(:person, :name) % > #assumes the controller has a @person set |
|
Model objects helper second arg?
|
<%= text_field(:person, :name) %
the method name (usually attribute) to call on object |
|
what html does this translate to?
<%= text_field(:person, :name) %> #assuming current name=Henry |
<input id="person_name" name="person[name]" type="text" value="Henry"/>
|
|
where in the params is the value stored
<%= text_field(:person, :name) %> |
params[:person][:name]
|
|
<%= text_field(:person, :name) %>
If a person model has no name attribute in the db how will this work? |
Just saving any name= method
|
|
Why bind a form to an object?
|
Efficiency. If Person (model) has many attributes to edit then we would be repeating the name of the edited object many times
|
|
How to bind a form to article model and create a text field?
|
<%= form_for :article, @article, :url => { :action => "create" } do |f| %>
<%= f.text_field :title %> |
|
The form_for method yields what?
|
a form builder object
e.g. f form_for :article, @article do |f| #f can have input fields called off it |
|
form_for :article, @article
What is the difference between the first and second param |
1st parm is the model name
2nd param is the actual object being editted |
|
how to change the url form_for passes to?
|
form_for :article, @article, :url => { :action => "create" }
#turn to :<form action="/articles/create" |
|
<%= form_for :article, @article do |f| %>
<%= f. etc. %> how to access the inputs |
all the inputs have names of the form article[attribute_name]. Accordingly, in the action params[:article] will be a hash with keys :title and :body.
|
|
Once you've bound an object to a form using form for, what can you omit from the helper fields?
|
The object name. Code like this suffices:
<%= f.text_field :title %> |
|
how do you edit additional model objects with the same form
|
fields_for form builder nested with form_for
<%= form_for :person, @person do |person_form| %> <%= person_form.text_field :name %> <%= fields_for @person.contact_detail do |contact_details_form| %> |
|
When dealing with RESTful resources (i.e. you declared map.resources in the routes), calls to form_for can use what shortcut?
|
form_for(@article)
#uses record identification instead of #new form_for(:article, @article, :url => articles_path) #edit form_for(:article, @article, :url => article_path(@article), :html => { :method => "put" }) |
|
how is short-style form_for invocation is the same, regardless of the record being new or existing
|
it figures out if the record is new by asking record.new_record?
|
|
Rails will also automatically set the class and id of the form appropriately: a form creating an article would have id and class .....
|
new_article.
|
|
Rails will also automatically set the class and id of the form appropriately: If you were editing the article with id 23, the class would be set to ...... and the id to .....
|
edit_article (class)
edit_article_23 (id) |
|
How to create a form that submits to the articles controller inside the admin namespace?
|
form_for [:admin, @article]
#udpate - subbmitting to admin_article_path(@article) |
|
How to create a form that submits to the article controller inside the managment namespace, itself inside the admin namespace?
#i.e. deeply nested |
form_for [:admin, :management, @article]
|
|
most browsers don’t support methods other than “GET” and “POST” when it comes to submitting forms. How does Rails get around this?
|
Rails works around this issue by emulating other methods over POST with a hidden input named "_method", which is set to reflect the desired method:
<input name="_method" type="hidden" value="put" /> |
|
how to specify that a form should put rather than post?
|
form_tag(search_path, :method => "put")
|
|
how to make select boxes (form not bound to a model)?
|
<%= select_tag(:city_id, options_for_select([['Lisbon', 1], ['Madrid', 2], ...])) %>
|
|
The first argument to options_for_select is
|
a nested array where each element has two elements: option text (city name) and option value (city id).
options_for_select([['Lisbon', 1], ['Madrid', 2], ...]) |
|
how does options_for_select allow you to pre-select an option by passing its value.
|
pass it in as the second param (once the first param, the array, is closed)
<%= options_for_select([['Lisbon', 1], ['Madrid', 2], ...], 2) %> #adds the selected attribute to whatever has the value of 2 in the form |
|
how to make select boxes (form bound to a model)
|
#form_for :person
<%= f.select( :city_id, [['Lisbon', 1], ['Madrid', 2], ...]) %> #don’t have to worry about pre-selecting the correct city if the user already has one — Rails will do this for you by reading from the @person.city_id attribute. |
|
If you are using select (or similar helpers such as collection_select, select_tag) to set a belongs_to association you must pass the name of the .........
|
foreign key (in the example above city_id), not the name of association itself.
%= select(:person, :city_id, ... |
|
ActiveRecord::AssociationTypeMismatch: City(#17815740) expected, got String(#1138750) means
|
you prob passed name of an association to a form, rather than the foreign key it expected
|
|
<%= options_from_collection_for_select(City.all, :id, :name) %>
explain |
1st param -> bunch of objects (City.all)
2nd param - value for option (:id) 3rd param - text displayed (:name) As the name implies, this only generates option tags. T |
|
When working with model objects collection_select combines .....
|
select_tag with options_from_collection_for_select.
<%= collection_select(:person, :city_id, City.all, :id, :name) %> |
|
To leverage time zone support in Rails, you have to ask your users what time zone they are in. Easiest way to do this?
|
<%= time_zone_select(:person, :time_zone) %>
|
|
Dates and times are not representable by a .... input element
|
Single. Instead you have several, one for each component (year, month, day etc.) and so there is no single value in your params hash with your date or time.
|
|
How to specify a barebones date / time helper (_tag suffix equivalent)
|
select_date, select_time and select_datetime
#select comes before with barebones select_* |
|
How to specify a model object date / time helper?
|
date_select, time_select and datetime_select
#select comes after with object |
|
What is the first argument of the select_* family of date / time helpers
|
an instance of Date, Time or DateTime that is used as the currently selected value.
<%= select_date Date.today %> |
|
What happens if you omit the first argument of the select_* family of date . time helpers (first param is current selected value)...
|
It use the current date
|
|
<%= select_date Date.today, :prefix => :start_date %> results in what params
|
params[:start_date][year]
params[:start_date][month] params[:start_date][day] |
|
How do you turn the output of a select_date helper into an actual Date or Time object?
#necessary since the three params it produces are just strings |
extract these values and pass them to the appropriate constructor, for example
Date.civil(params[:start_date][:year].to_i, params[:start_date][:month].to_i, params[:start_date][:day].to_i) |
|
How to create an object bound date/time select for the birth_date attribute of a person model
|
<%= date_select :person, :birth_date %>
|
|
How is this represented in HTML and why? <%= date_select :person, :birth_date %>
|
<select id="person_birth_date_1i" name="person[birth_date(1i)]"> ... </select>
<select id="person_birth_date_2i" name="person[birth_date(2i)]"> ... </select> etc. #the 1i,2i,3i (not shown) are used by AR to construct the birth_date attribute |
|
How is this represented in the params <%= date_select :person, :birth_date %>
|
{:person => {'birth_date(1i)' => '2008', 'birth_date(2i)' => '11', 'birth_date(3i)' => '22'}}
|
|
By default Rails date time helpers generate year options how many years each side of the current year?
|
5 years
To overide pass a :start_year and an :end_year option |
|
As a rule of thumb you should be using date_select when .... and select_date i...
|
date select when working with model objects
select_date in other cases, such as a search form which filters results by date |
|
How to specify a single date component such as a year or a month.
|
select_year, select_month, select_day, select_hour, select_minute, select_second
|
|
select_year, select_month, select_day, etc. generate an input field named after....
|
input field named after the time component (for example “year” for select_year, “month” for select_month etc.) although this can be overriden with the :field_name option.
|
|
How to set the selected value of select_year, select_month, select_day, etc.
|
either be an instance of a Date, Time or DateTime,
<%= select_year(2009) %> <%= select_year(Time.now) %> |
|
<%= select_year(2009) %> is a instance of the singular date helpers. How do you access these params in the controller
|
the value chosen by the user can be retrieved by params[:date][:year].
|
|
What must you do to be able to upload files to a form?
|
Set the form's encoding to multippart/form-data
<% form_for @person, :html => {:multipart => true} do |f| %> |
|
What is the difference between setting multi-part to true for form_tags and form_forms?
|
<% form_tag({:action => :upload}, :multipart => true) do %>
#passed in the second options hash (which is the html one) <% form_for @person, :html => {:multipart => true} do |f| %> #passed as a html option |
|
What form helper is used to upload files for form_fors
|
<%= f.file_field :picture %>
|
|
What form helper is used to upload files for form_tags
|
<%= file_field_tag 'picture' %>
|
|
The file object in the params hash is an instance of a ....
|
subclass of IO
|
|
How to access the file just uploaded in a Rails form in the params?
|
params[:person][:picture]
# good practice is to assign this to a var e.g pic = p |
|
what attribute do uploaded file objects have
|
original_filename
thus uploaded_io = params[:person][:picture] uploaded_io.original_filename |
|
making an asynchronous file upload form is not as simple as replacing form_for with remote_form_for. Why? Workaround?
|
With an Ajax form the serialization is done by JavaScript running inside the browser and since JavaScript cannot read files from your hard drive the file cannot be uploaded. The most common workaround is to use an invisible iframe that serves as the target for the form submission.
|
|
form_for and fields_for are subclasses of?
|
FormBuilder
|
|
How to build custom Form builders?
|
class LabellingFormBuilder < ActionView::Helpers::FormBuilder
def text_field(attribute, options={}) label(attribute) + super end end |
|
How to use a custom form builder (LabellingFormBuilder in this case)
|
<% form_for @person, :builder => LabellingFormBuilder do |f| %> <%= f.text_field :first_name %> <% end %>
#assumes you've elsewhere defined t |
|
HTML forms don’t know about any sort of structured data, all they generate is ...
|
name-value pairs - where both are just plain strings
|
|
How to try out rails paramater parser in the console?
|
ActionController::UrlEncodedPairParser.parse_query_parameters “name=fred&phone=0123456789”
|
|
For a params hash of {'person' => {'name' => 'Henry'}} what will the input form look like?
|
<input id="person_name" name="person[name]" type="text" value="Henry"/>
#note the id outerkey_innerkey and name = outerkey[innerkey] and value = value |
|
How will a tri nested params hash look?
{'person' => {'address' => {'city' => 'New York'}}} |
<input id="person_address_city" name="person[address][city]" type="text" value="New York"/>
#look at how its outermostkey_middlekey_innerkey in id and out[mid][inner] in name |
|
How to accumulate params in an array?
|
The parameter name must contain an empty set of square brackets []
<input name="person[phone_number][]" type="text"/> <input name="person[phone_number][]" type="text"/> #two phone numbers |
|
How to make params[:person][:phone_number] an array instead of a single item?
|
<input name="person[phone_number][]" type="text"/>
<input name="person[phone_number][]" type="text"/> |
|
How to make params[:addresses] an array of hashes each with keys line1, line2 and city?
|
#put the square brackets after the item which is supposed to contain an arrary - then deeper nested items will dictate the hash structure of said array
<input name="addresses[][line1]" type="text"/> <input name="addresses[][line2]" type="text"/> <input name="addresses[][city]" type="text"/> |
|
What restriction is placed on arrays in params?
|
only one level of “arrayness” is allowed -i.e. no deep nesting
|
|
Whats a good way to represent a set of models in params using hashes?
|
a hash of model objects keyed by their id
|
|
check_box helper doesn't play well with arays since the duplicate input names created by the hidden input submitted when unchecked confuses Rails (doesn't know whether array or not). What to use instead?
|
check_box_tag
|
|
What form action html is created by this edit form (assuming person has id of 1)?
<% form_for @person do |person_form| %> |
#/people/1 - a url
# and method =post <form action="/people/1" class="edit_person" id="edit_person_1" method="post"> |
|
What class does this edit form (assuming person has id of 1)?
<% form_for @person do |person_form| %> create? |
#edit_person
<form action="/people/1" class="edit_person" id="edit_person_1" method="post"> |
|
What id does this edit form (assuming person has id of 1)?
<% form_for @person do |person_form| %> create? |
#edit_person_1
# items id is used <form action="/people/1" class="edit_person" id="edit_person_1" method="post"> |
|
. If you pass an Active Record object as we did then Rails will call to_param on it, which by default returns the ......
|
database id.
#thus @person.to_param = 23 |
|
What does the index option for form_for and fields_for do?
<% person_form.fields_for address, :index => address |
it inserts that index between the preceding and following param
person[address][ *index_item* ] person[address][4] actually (since the index is passed an AR object) |
|
How to get params like this?
{'person' => {'name' => 'Bob', 'address' => {'23' => {'city' => 'Paris'}, '45' => {'city' => 'London'}}}} |
form_for person
f.name for address in @person.addresses #setting the variable fields_for address :index => address |
|
What is the advantage of params like this?
{'person' => {'name' => 'Bob', 'address' => {'23' => {'city' => 'Paris'}, '45' => {'city' => 'London'}}} |
#great for locating which AR record to modify
|
|
How to specify the first part of the input name (person[address] explicity?
|
<% fields_for 'person[address][primary]', address do |address_form| %>
|
|
How to generate a generator?
|
rails g generator NAME
|
|
When you generate a generator (within a rails app) where do the files go?
|
lib/generator-name/
|
|
Every ...... in the x_generator.rb file will be run when that generator is called in future.
|
public method
|
|
If you want to create a method in a generator which is not automatically run when the generator is call ed make is a .....
|
private method
|
|
By default a generated generator inherits from
.... |
Rails::Generators::NamedBase
|
|
Rails::Generators::NamedBase inheritance means that ....
|
a name must be supplied when calling the generator
|
|
If you want the supply of a name to be optional when calling a generator change the inheritance to inherit from .....
|
Rails::Generators::Base
|
|
What method is used to define arguments for your generator? (i.e. extra bits that can be entered at command line and assigned as variables within the generator?
|
argument :layout_name, :type => :string
#write this just under the source_path method |
|
How to give an argument in a generator a default should nothing be provided at command line?
|
argument :layout_name, :type => :string
|
|
when you run rails g layout --help and you see an argument in square brackets (e.g. [LAYOUT_NAME] what does this mean?
|
that the argument is optional
|
|
By default where do you put files within a generator which you want to copy over to the application when the generator is run?
|
the template folder
|
|
How should you name the public methods in your generator?
|
after what they create (e.g. generate_stylesheet) - helps organize code better
|
|
How to copy the "stylesheet.css" file from the template folder in a generator to your app?
|
copy_file "stylesheet.css", "public/stylesheets/#{layout_name}"
|
|
copy_files 2nd param is?
|
where you want the copied file to end up in your app - director name and filename
copy_file "stylesheet.css", "public/stylesheets/#{layout_name}.css" |
|
Rails only method to turn a CamelCased string into an underscored_one
|
.underscore
#useful for formatting arguments which will be turned into filenames |
|
Difference between copy_file and tempalte
|
copy_file does a straight copy of file without modifying it at all - template modifyes the resulting file when the generator runs
|
|
The template method will execute all the ....
|
erb tags within the .erb file you are templating. Bad since might cause generator to crash with unknown methods
|
|
How to modify erb template files so that template method doesn't execute all the erb
|
change <% and <%= to <%% and <%%=
#i.e. change the first one so as to escape it |
|
Within template files of a generator how do you access methods within the x_generator.rb file
|
<%= method_name %>
#regular unescaped erb here #can even use private methods |
|
How to add a cmd line option to you generator
|
before declaring the public methods call class_option :stylesheet, :type => boolean, :default => true, :desc => "Include Stylesheet File"
|
|
How to access command line options within a generator?
|
call the option name from the options object
e.g. options.stylesheet if you declared class_option :stylesheet |
|
How to make copying certain fiels within the generator optional?
|
copy file ..... if options.stylesheet?
#where this is a boolean defaulting to true |
|
How to remove certain lines from a tempalte depending on command line options?
|
<%- if options.sytlesheet? -%>
dfdsfs <%- end -%> |
|
How to put a generator in a gem so as to share with others?
|
Create a dir in the gem called lib/generators are place you generator inside. Once they include the gem in their application it will be available for them to use
|
|
How to see all the generators available to your app?
|
rails g
#will show the generators available for different items for different tasks (e.g. shoulda might have model but not scaffold) |
|
How to see options with a given generator (e.g. scaffold?
|
rails g scaffold --help
|
|
Many generator options have ...
|
default values (seen with --help)
|
|
How to disable a boolean that defaults to try in a generator
e.g. -stylehsheets defaults to true |
--no in front of option name
rails g scaffold --no-sytlesheets |
|
In the output of a generator what does invoke mean?
|
invokes a separate generator - shows that a high level generator delegates work onto other generators - e.g. scaffold invokes acive_record generator
|
|
How do you have a generator option added everytime you run a generator without typing it every time?
|
application.rb
config.generators do |g| g.tempalte_engine :haml end #put any options you saw in the generator help |
|
To use certain generator options you need to ensure the gems are ...
|
added to the Gemfile
|
|
If your gem doesn't include generators then you should check ...
|
gem "rails3-generators", :group => :development
#this gives you lots of new generators only in dev area so production not clogged up |
|
If you see error shoulda [not found] in place of invoke when running a generator what does this mean?
|
Rails could not find a shoulda generator for the high level task (e.g. rails g scaffold)
|
|
What is a generator fallback?
|
Says that if a generator is not found (e.g. shoulda) it will use someting else
#within the generator block g.fallbacks[:shoulda] = :test_unit |
|
Where to put generator fallbacks ?
Rails::Generators.fallbacks[:shoulda] = :test_unit |
at the bottom of the application.rb file
|
|
How to override the tempalte of the generators rails gives you?
|
add files to lib/templates
|
|
How to find name of the templates you wish to override with your generator!
|
railes/railties/lib/rails/generators/ on rails github
#thus for ...generators/scaffold/erb/index.html.erb you need to create a dir in the lib/templates dir locally called erb/scaffold |
|
How to add a description to your custom generator?
|
1. Call the desc method within the generator (just under the class defition and inheritance)
desc "This generator creates an initializer file at config/initializers" 2. Create a USAGE file |
|
What method is automatically created when we inherit from Rails::Generators::NamedBase.
|
file_name - set to argument supplied at cmd line
|
|
How to use the create_file method in a generator
|
#second parm is file contents and is between <<--FILE and FILE
create_file "app/helpers/#{file_name}_helper.rb", <<-FILE module #{class_name}Helper attr_reader :#{plural_name}, :#{plural_name.singularize} end FILE end |
|
What are hooks within generators?
|
Generators do not need to be focused in one specific test framework, it can simply provide a hook and a test framework just needs to implement this hook in order to be compatible.
|
|
How to use a hook within a generator for test framework?
|
hook_for :test_framework
|
|
When TestUnit is configured as the test framework and it sees hook_for :test_framework within a class MyHelperGenerator what will it try to invoke?
|
MyHelper::Generators::TestUnitGenerator
#this is undefined - instead it only sees helper |
|
How to specify in a generator hook to look for a different generator to invoke
|
# Search for :helper instead of :my_helper hook_for :test_framework, :as => :helper
|
|
Within a template file how do you get a class to dynamically be input?
|
<%= class_name %>
|
|
Within a template file how do you get the plural name to dynamically be input?
|
<%= plural_name %>
|
|
Within a template file how do you get the singular name to dynamically be input?
|
<%= plural_name.singularize %>
|
|
What do hooks do in generators?
|
allow one generator to call another
|
|
What order do arguments and options to a generator come in when parsing params?
|
first params are arguments, last ones are options
|
|
The order arguments are decalred in a generator is ....
|
the order they will be accepted on the command line
|
|
how to specify a generator argument in a number
|
:type => :numeric
|
|
Once an argument to a generator is declared optional, all remaining arguments....
|
must be optional
|
|
Once an array argument is declared (:type => :array) everything after it is
|
parsed into the array
|
|
How to set an option when calling a generator?
|
--name-of-option
|
|
Generators inherit all the methods of what useful file manipulation suite?
|
Thor::Actions
|
|
How to add a single line of text to the end of a file with a generator?
|
append_file 'config/environments/test.rb', 'config.gem "rspec"
|
|
How to add multiple lines of text to the end of a file with a generator?
|
append_file 'config/environments/test.rb' do
'config.gem "rspec"' end |
|
How to add a single line of text to the TOP of a file with a generator?
|
prepend_file 'config/environments/test.rb', 'config.gem "rspec"'
|
|
How to run a regular expression replacement on a file in a generator?
|
gsub_file 'app/controllers/application_controller.rb', /app_name/, 'hermestech'
|
|
What is the 2nd param for gsub_file?
|
the flag - regex or string to be replaced
|
|
What is the 3rd param for gsub_file
|
the replacement text (can be given as a block too)
|
|
How to download the content at the given address and places it at the given relative destination?
|
get "http://gist.github.com/103208", "doc/README"
|
|
How to create an empty directory in a generator?
|
empty_directory "doc"
|
|
How to load an external file and execute it in a generator?
|
apply "http://gist.github.com/103208"
apply "recipes/jquery.rb" |
|
How to execute a linux command inside a generator?
|
run('ln -s ~/edge rails')
|
|
How to execute a linux command within a certain folder of the new app inside a generator?
|
inside('vendor') do
run('ln -s ~/edge rails') end |
|
How to remove a file from a rails app in a generator
|
remove_file 'app/controllers/application_controller.rb'
|
|
How to add text after a certain point in an existing file?
|
inject_into_file "config/environment.rb", "config.gem :thor", :after => "Rails::Initializer.run do |config|\n"
|
|
How to add text right after the class definition of an existing class?
|
inject_into_class "app/controllers/application_controller.rb", " filter_parameter :password\n"
|
|
How to run git commands it a rails generator?
|
git :command => "arg"
git :init git :add => '.' git :commit => "-a -m 'Initial commit'" |
|
How to add routes in a rails generator?
|
route "map.root :controller => 'pages', :action => 'index'"
|
|
How to run a generator from a rails generator
|
generate :controller, "pages index"
#first param is generator type, second is args |
|
How to add a gem from a Rails generator?
|
gem 'inherited_resources', :version => '1.0.3'
|
|
How to run a rakefile from a Rails generator?
|
rake "db:migrate"
|
|
how to install a plugin from a generator?
|
plugin "dry_scaffold", :git => "git://github.com/stasl/dry_scaffold.git"
|
|
Find the client with primary key (id) 10.
|
client = Client.find(10)
|
|
sql equivalent of client = Client.find(10)
|
SELECT * FROM clients WHERE (clients.id = 10)
|
|
ActiveRecord::RecordNotFound is raised when
|
Model.find(primary_key) doesnt find any records
|
|
How to find the first record matched by the supplied options
|
client = Client.first
|
|
sql equivalent of client = Client.first
|
SELECT * FROM clients LIMIT 1
|
|
Does client.first raise an exception if no matches are found (like find(1) would)?
|
no - nil is returned if no matches are found
|
|
finds the last record matched by the supplied options
|
client = Client.last
|
|
sql equivalent of client = Client.last
|
SELECT * FROM clients ORDER BY clients.id DESC LIMIT 1
|
|
Find the client with primary key (id) 1 and 10 in one go
|
client = Client.find(1, 10)
|
|
sql equivalent of client = Client.find(1, 10)
|
SELECT * FROM clients WHERE (clients.id IN (1,10))
|
|
When the user table has 1000s of rows what is wrong with this code?
User.each do |user| NewsLetter.weekly_deliver(user) end |
INefficient
This is because User.each makes Active Record fetch the entire table, build a model object per row, and keep the entire array in the memory. Sometimes that is just too many objects and demands too much memory. |
|
What does find_each do?
|
find_each fetches rows in batches of 1000 and yields them one by one
#much more efficient when a table has thousands of rows |
|
how to configure the batch size of find_each?
|
option :batch_size => 2000
User.find_each(:batch_size => 5000) do |user| NewsLetter.weekly_deliver(user) end |
|
How to start a batch find from a specific primary key
|
User.find_each(:batch_size => 5000, :start => 2000) do
|
|
What is the diff between find_each and find_in_batches?
|
find_in_batches yields arrays of models (each array of batch size) instead of a singular item like find_each
# Works in chunks of 1000 invoices at a time. Invoice.find_in_batches(:include => :invoice_lines) |
|
find all clients where the orders_count field’s value is 2.
|
Client.where("orders_count = '2'")
|
|
when using the AR where clause with one condition be sure to wrap it in ....
|
quotes "...."
Client.where("orders_count = '2'") |
|
when using the where clause and looking for equal do you use single or double equals?
|
single
Client.where("orders_count = '2'") |
|
when using AR where clause with an argument that varies what do you do?
|
wrap the entire clause in an [], with the first element being the condition (substituting a ? for the variable), and the second condition being the variable to substitute in
Client.where(["orders_count = ?", params[:orders]]) |
|
how to specify two variables with AR where clause
|
use two questions marks and pass in three elements total to the clause (last two being the variables values)
Client.where(["orders_count = ? AND locked = ?", params[:orders], false]) |
|
Why write code like
Client.where(["orders_count = ?", params[:orders]]) instead of Client.where("orders_count = #{params[:orders]}") |
rgument safety. Putting the variable directly into the conditions string will pass the variable to the database as-is. This means that it will be an unescaped variable directly from a user who may have malicious intent.
|
|
Give an alternative way to write this using hashes
Client.where(["orders_count = ?", params[:orders]]) |
Client.where(["orders_count = :order_count", {:orders_count => params[:orders]}])
#useful where large number of vars as it aids readability |
|
If you’re looking for a range inside of a table (for example, users created in a certain timeframe) what sql are you looking for
|
#IN
... WHERE (created_at IN ('2007-12-31','2008-01-01','2008-01-02','2008-01-03') |
|
If you’re looking for a range inside of a table (for example, users created in a certain timeframe) what AR would you use
|
Client.where(["created_at IN (?)", (params[:start_date].to_date)..(params[:end_date].to_date)])
#note the "...IN (?)" #and the (start)...(end) |
|
What is the general structure for a range query
|
MOdel.where(["field AT (?)", (value)..(value2)
]) |
|
How to find clients created after a certain date?
|
#pass in a greater than sql sign to the query
Client.where( ["created_at > ? A", params[:start_date]] ) |
|
How to use a hash condition to search for locked clients (boolean)
|
Client.where({ :locked => true })
|
|
Client.where({ :locked => true }) can also be written as...
|
a string instead of a sybmol
Client.where({ 'locked' => true }) |
|
Never pass a ... object to sql
|
Time object
it will attempt to compare your field to every second in that range resulting in shit loads of queries |
|
How to find all the clients who have 1,3 or 5 orders?
|
Client.where({ :orders_count => [1,3,5] })
|
|
What is the sql for Client.where({ :orders_count => [1,3,5] })
|
SELECT * FROM clients WHERE (clients.orders_count IN (1,3,5))
|
|
Get a set of records and want to order them in ascending order by the created_at field in your table:
|
Client.order("created_at")
|
|
Get clients in descending order of created at
|
Client.order("created_at DESC")
|
|
Get clients in ascending order of created at
|
Client.order("created_at ASC")
|
|
How to order by multiple fields
|
Pass them in as elements separated by commas to the order condition
Client.order("orders_count ASC, created_at DESC") |
|
How to to select only viewable_by and locked columns:
|
Client.select("viewable_by, locked")
|
|
What is the consequence of using the select AR method
|
If the select method is used, all the returning objects will be read only.
|
|
What sql does this create:
Client.select("viewable_by, locked") |
SELECT viewable_by, locked FROM clients
|
|
When using select If you attempt to access a field that is not in the initialized record you’ll receive:
|
ActiveRecord::MissingAttributeError: missing attribute: <attribute>
Where <attribute> is the attribute you asked for. |
|
How to grab a single record per unique value in a certain field - i.e. only get the differing names
|
pass in sql DISTINCT(attr_name) to the select
Client.select("DISTINCT(name)") |
|
How to limit a query to only 5 matches
|
Client.limit(5)
|
|
What sql does this create:
Client.limit(5) |
SELECT * FROM clients LIMIT 5, 5
|
|
How to get records starting from only the 100 record in the table
|
Client.offset(100)
|
|
What sql does this create:
Client.limit(5).offset(100) |
SELECT * FROM clients LIMIT 5, 100
|
|
if you want to find a collection of the dates orders were created on: (where there are multiple orders per date sometimes and none othertimes)
|
Order.group("date(created_at)")
|
|
How to explicitly disallow modification/destruction of the matching records returned in a Relation object,
|
Client.first.readonly(true)
|
|
what happens if you try to modify a read only attribute
|
ActiveRecord::ReadOnlyRecord exception:
|
|
Optimistic locking works by...
|
checking whether another process has made changes to a record since it was opened returning an ActiveRecord::StaleObjectError exception
|
|
If you try to update something which someone else is already updating (and optimistic locking is on) what happens?
|
ActiveRecord::StaleObjectError exception
and the udpate is ignored |
|
for optimistic locking to work...
|
the table needs to have a column called lock_version.
|
|
You must ensure that your database schema defaults the lock_version column to
|
0.
|
|
How to stop locking once set up?
|
ActiveRecord::Base.lock_optimistically = false.
|
|
How to override the name of the lock_version column
|
class Client < ActiveRecord::Base set_locking_column :lock_client_column
end |
|
Pessimistic locking uses
|
locking mechanism provided by the underlying database
|
|
How to use pessimistic looking?
|
On a per find basis
Passing :lock => true to Model.find obtains an exclusive lock on the selected rows Item.first(:lock => true) |
|
How to do an inner join on categories and posts
|
Category.joins(:posts)
|
|
How to do an inner join on categories and posts AND comments (3 way)
|
Post.joins(:category, :comments)
|
|
How to specify conditions on a join table - e.g. Client calling join or orders but requires it within a certain (predefined) timerange
|
Client.joins(:orders).where(:orders => {:created_at => time_range})
#note the use of symbol with the join table name within the where condition and using a hash as the value |
|
How many queries does this execute?
clients = Client.all(:limit => 10) clients.each do |client| puts client.address.postcode end |
xecutes 1 ( to find 10 clients ) + 10 ( one per each client to load the address ) = 11 queries in total.
classic n+1 problem |
|
what method is used to get around the n+1 problem
|
includes
clients = Client.includes(:address).limit(10) now looping through clients.address doesn't require extra queries |
|
How many queries does this execute?
clients = Client.includes(:address).limit(10) clients.each do |client| puts client.address.postcode end |
Only 2
SELECT * FROM clients LIMIT 10 SELECT addresses.* FROM addresses WHERE (addresses.client_id IN (1,2,3,4,5,6,7,8,9,10)) |
|
How to eager load any possible number of associations with a single Model.find
|
Post.includes(:category, :comments)
|
|
If you have a field called first_name on your Client model for example, you get what 3 dynamic finder methods for free??
|
find_by_first_name
find_all_by_first_name find_last_by_first_name # note the LAST |
|
Whats the diff between
Client.find_by_name("Ryan") and Client.find_by_name!("Ryan") |
specifying a ! at the end gets dynamic finders to raise ActiveRecord::RecordNotFound error if they do not return any records
|
|
How to create/initialize objects if they aren’t found.
|
find_or_create_by_first_name(params[:first_name])
|
|
How does this work:
find_or_create_by_first_name(params[:first_name]) |
will firstly perform a find and then create if the find returns nil.
|
|
diff between
find_or_initialize_by_attr_name and find_or_create_by_attr_name |
initialize is like calling new(doesnt save to db), whereas create is calling create (and saves to db)
|
|
How to simply want to check for the existence of the object without returning it
returns true or fals |
Client.exists?(1)
#where 1 is the id |
|
how to specify conditions with the exists? method
|
Client.exists?(:conditions => "first_name = 'Ryan'")
|
|
How to count number of items in db (makes a fresh call)
|
count method
Client.count(:conditions => "first_name = 'Ryan'") |
|
diff between .size and .count
|
.count always calls db afresh, .size wont if realationship is already populated
|
|
How many clients in Client table?
|
Client.count
|
|
How many clients in Client table who have given their age attribute?
|
Client.count(:age).
|
|
How to get the average of the orders_count attr?
|
Client.average("orders_count")
|
|
How to get the minimum of the age attr?
|
Client.minimum("age")
|
|
How to get the maximum of the age attr?
|
Client.maximum("age")
|
|
How to get the sum of all the orders_count fields on all the records
|
Client.sum("orders_count")
|
|
how to evoke rails server (previously script/server)
|
rails server
|
|
how to get help in any rails command line utility
|
append -h or --help
|
|
how to evoke rails console (previously script/console)
|
rails console
|
|
How to drop into whichever db your using's command line interface (SQL< PosgreSQL whatever)
|
rails dbconsole
|
|
how to add a plugin
|
rails plugin http://wherever
|
|
how to undo a model generate for Opps
|
rails destroy model Oops
|
|
what does destroy do
|
It’ll figure out what generate did, and undo it.
|
|
How to check ruby version number?
|
rake about
|
|
How to check Rails version?
|
rake about
|
|
How to check migration schema?
|
rake about
|
|
How to use a different server for rails?
|
install its gem (e.g. gem install mongrell)
then call rails server mongerl |
|
See all rake task available?
|
rake -T
|
|
rake db:create
rake db:charset rake db:migrate what do these ahve in common |
all are namespaced by db
|
|
what is rake:notes for
|
earch through your code for commented lines beginning with “FIXME”, “OPTIMIZE”, “TODO”, or any custom annotation (like XXX) and show you them.
|
|
what is rake docs for
|
strip out or rebuild any of the Rails documentation (including this guide!),
|
|
view all timezones rails know about
|
rake time:zones:all
|
|
remove tmp files
|
rake tmp:clear
|
|
see stats such as test ratio and LOC
|
rake stat
|
|
see all defined routes
|
rake routes
|
|
when rails receives an incoming request like
GET /patients/17 what does it do |
it asks the router to match it to a controller action. thus the dsl
match "/patients/:id" => "patients#show" |
|
how does the routing system represent variables in the url
|
prepend a :
e.g. patients/:id |
|
Resource routing allows you to
|
quickly declare all of the common routes for a given resourceful controller
resources :photos #instead of sep route for index, show etc. |
|
Index action is what url and verb
|
GET /photos
#same as create except a GET |
|
New action is what url and verb
|
GET /photos/new
#note it's get as nothing is posted yet (its still new) #note too the necessity of adding the /new (only other with an extra word is edit) |
|
Create action is what url and verb
|
POST /photos
#same as index except a POST |
|
Show action is what url and verb
|
GET /photos/:id
#even though your getting a singular item it's still photos |
|
Edit action is what url and verb
|
GET /photos/:id/edit
#even though your getting a singular item it's still photos |
|
Update action is what url and verb
|
PUT /photos/:id
#even though your getting a singular item it's still photos |
|
Delete action is what url and verb
|
DELETE /photos/:id
#even though your getting a singular item it's still photos |
|
what discrepancy exists between the helper for the show path and the way the url is written
|
photo_path(id) - singular photo
photos/:id - plural photo |
|
helper for new or edit photo
|
new_photo_path
edit_photo_path |
|
Give an example of a resource that clients will ook up with referencing an ID (ie a show without an id)
|
/profile always shows the profile of the currently logged in user.
|
|
how to create a singular resouce, i.e. one with no index action
|
resource :geocoder
instead of resources :geocode |
|
How to organize controllers under an Admin:: namespace
|
namespace "admin" do
resources :posts, :comments end |
|
If you had this code where would you palce the posts and comments controllers
namespace "admin" do resources :posts, :comments end |
app/controllers/admin
|
|
what does the photos index path look like
namespace "admin" do resources :posts, :comments end |
admin_photos_pah
#admin is singular just as it was defined in the namespac |
|
what does the photos edit path look like
namespace "admin" do resources :posts, :comments end |
edit_admin_photo_path(id)
#edit prepends all, but straight after is admin art |
|
what does the index url for photso look like
namespace "admin" do resources :posts, :comments end |
/admin/photos
#/admin in front |
|
f you want to route /photos (without the prefix /admin) to Admin::PostsController, you could use
|
#use the scope :module => "namespace" construction
scope :module => "admin" do resources :posts, :comments end |
|
For a single case whats a quicker way of writing
scope :module => "admin" do resources :posts, :comments end |
#omit the scope and must do :module => "namespace"
resources :posts, :module => "admin" |
|
If you want to route /admin/photos to PostsController (without the Admin:: module prefix), you could use
|
#use scope with a url as the first argument instead
scope "/admin" do resources :posts, :comments end |
|
Quicker way of writing
scope "/admin" do resources :posts, :comments end |
resources :posts, :path => "/admin"
|
|
HOw to capture nested resources in routing?
|
resources :magazines do
resources :ads end |
|
How to see a list of all magazines?
resources :magazines do resources :ads end |
/magazines/1/ads
|
|
How to see a display a specific ad belonging to a specific magazine
resources :magazines do resources :ads end |
/magazines/1/ads/1
|
|
How to return an HTML form for creating a new ad belonging to a specific magazine
resources :magazines do resources :ads end |
/magazines/1/ads/new
|
|
Resources should never be nested more than ....
|
1 level deep.
|
|
When using magazine_ad_path, you can pass in..... instead of the numeric IDs.
|
instances of Magazine and Ad
magazine_ad_path(@magazine, @ad) |
|
shortest link_to for the show path of a specific magazine
|
<%= link_to "Magazine details", @magazine %>
|
|
shortest link_to for the show path of a specific ad nested in a specific magazine
|
<%= link_to "Ad details", [@magazine, @ad] %>
#note the array used to store all the values within the second argument |
|
how to add an additional route which acts on an individual member of a resource collection (imagine we had a preview action on a photo controller)
|
resources :photos do
get :preview, :on => :member end |
|
how to add an additional route which acts on the collection of a resource (imagine we had a search action on a photo controller)
|
resources :photos do
collection do get :search end end |
|
Structure of an additional route which acts on an individual member of a resource collection
|
inside the resources block
verb :method_name :on => :member e.g. get :preview, :on => :member |
|
Structure of an additional route which acts on a collection of a resource collection
|
inside the resource block
get :search, :on => :collection |
|
Dif between member and collection resource route additions
|
collection r has an additional :on => :collection arg
member has an additional :on => :member arg verb :method_name :on => :member |
|
If you find yourself adding many extra actions to a resourceful route, it’s time to
|
stop and ask yourself whether you’re disguising the presence of another resource.
|
|
How to make part of a route optional
|
surround it with (/ ) where the closing parenthiss continues till the end of the route
match ':controller(/:action(/:id))' |
|
match ':controller/:action/:id/:user_id'
what params are available |
params[:id]
and params[:user_id] |
|
shortest link_to for the show path of a specific magazine
|
<%= link_to "Magazine details", @magazine %>
|
|
shortest link_to for the show path of a specific ad nested in a specific magazine
|
<%= link_to "Ad details", [@magazine, @ad] %>
#note the array used to store all the values within the second argument |
|
how to add an additional route which acts on an individual member of a resource collection (imagine we had a preview action on a photo controller)
|
resources :photos do
get :preview, :on => :member end |
|
how to add an additional route which acts on the collection of a resource (imagine we had a search action on a photo controller)
|
resources :photos do
collection do get :search end end |
|
Structure of an additional route which acts on an individual member of a resource collection
|
inside the resources block
verb :method_name :on => :member e.g. get :preview, :on => :member |
|
Structure of an additional route which acts on a collection of a resource collection
|
inside the resource block
get :search, :on => :collection |
|
Dif between member and collection resource route additions
|
collection r has an additional :on => :collection arg
member has an additional :on => :member arg verb :method_name :on => :member |
|
If you find yourself adding many extra actions to a resourceful route, it’s time to
|
stop and ask yourself whether you’re disguising the presence of another resource.
|
|
How to make part of a route optional
|
surround it with (/ ) where the closing parenthiss continues till the end of the route
match ':controller(/:action(/:id))' |
|
match ':controller/:action/:id/:user_id'
what params are available |
params[:id]
and params[:user_id] |
|
How can specify what Rails should route "/" to?
|
root :to => 'pages#main'
|
|
Give an example of a static segment within a route
|
match ':controller/:action/:id/with_user/:user_id'
|
|
what params does this have
/photos/show/1?user_id=2 |
{ :controller => “photos”, :action => “show”, :id => “1”, :user_id => “2” }.
query string is converted to a param |
|
How to get params[:format] as "jpg" without specifying a dynamic segment in the route
|
match 'photos/:id' => 'photos#show', :defaults => { :format => 'jpg' }
|
|
how to give a route a custom name?
|
massing the :as => :name option
match 'exit' => 'sessions#destroy', :as => :logout |
|
what two things does this generate?
match 'exit' => 'sessions#destroy', :as => :logout |
logout_path helper
and the url /logour |
|
How to to enforce a format for a dynamic segment:
|
passing a constrainsts => { :param_name => /regex/ } option
match 'photo/:id' => 'photos#show', :constraints => { :id => /[A-Z]\d{5}/ } |
|
more succint way to express
match 'photo/:id' => 'photos#show', :constraints => { :id => /[A-Z]\d{5}/ } |
match 'photo/:id' => 'photos#show', :id => /[A-Z]\d{5}/
|
|
:constraints takes regular expression. However note that .... can’t be used within constraints.
|
regexp anchors
thus this wont work match '/:id' => 'videos#show', :constraints => {:id => /^\d/} |
|
how to use globbing to match photo/long/path/to/12, setting params[:other] to "long/path/to/12".
|
match 'photo/*other' => 'photos#unknown'
|
|
how to redirect from /stories to the post controller?
|
match "/stories" => redirect("/posts")
|
|
how to redirect from /stories to the poast controller - this time passing over dynamic segments
|
match "/stories/:name" => redirect("/posts/%{name}")
#note the interpopated ruby within the match string which mirrors the original symbol |
|
how to have a url say one thing yet use a different controller (resourceful)
|
resources :photos, :controller => "images"
|
|
resources :photos, :controller => "images"
what are the helpers here |
still
photos_path etc. |
|
how to specify constraints for a restful url?
|
resources :photos, :constraints => {:id => /[A-Z][A-Z][0-9]+/}
|
|
How to override the normal naming for the named route helpers.
|
#an as option which has the string to rename the named routes with
resources :photos, :as => "images" gives you url or /photos but helpers of images_path |
|
how to verride the automatically-generated “new” and “edit” segments in URLs:
|
#a path_names option which has a hash with :new and :edit mapped to their new names
resources :photos, :path_names => { :new => 'make', :edit => 'change' } |
|
how to limit the routes created for a resource to only index and show
|
resources :photos, :only => [:index, :show]
|
|
How to specify a list of routes that Rails should not create for a resource?
|
resources :photos, :except => :destroy
|
|
Advantage of using :only and :except on resource routes?
|
can cut down on memory use and speed up the routing process.
|
|
Callbacks allow you to ....
|
to trigger logic before or after an alteration of an object’s state.
|
|
Validations ensure that....
|
only valid data is stored in your database.
|
|
Client side validations (with JS) can be a ...
|
convenient way to provide users with immediate feedback as they use your site.
|
|
What are the two kinds of Active Record objects:
|
those that correspond to a row inside your database and those that do not.
|
|
AR uses what instance method to determine whether an object is already in the database or not?
|
new_record?
|
|
how to create a person object with name attr John Doe?
|
Person.new(:name => "John Doe")
|
|
Using save! or create! or update_attributes! what happens if a record is invalid?
|
exception raised
|
|
Using save or update_attributes what happens if a record is invalid?
|
save and update attributes return false
|
|
Using create or update what happens if a record is invalid?
|
you get the original object
|
|
how to bypass validations with save
|
save(false)
|
|
What special behaviour do the following have vis a vis validations?
# update_all # update_attribute |
they don't run validations
#note that whilst udpate_attribute doesnt validate, update_attributes does |
|
What method triggers your validations and returns true if no errors were added to the object, and false otherwise.
|
valid?
|
|
bject instantiated with new wil ... even if it’s technically invalid, because validations are not run when using new.
|
not report errors
|
|
how to see the errors on an object in the console
|
p.errors
|
|
What method triggers your validations and returns true if any errors were added to the object, and
|
invalid?
|
|
How do you verify whether or not a particular attribute of an object is valid
|
>> Person.new.errors[:name].any? # => false
|
|
What important difference is there between Persion.errors[:name] and Person.valid?
|
errors[:attr] doesnt trigger validations - only checks if errors found on object
|
|
What 3 options does the :on option take in validation helpers?
|
:save (the default), :create or :update
|
|
Validates that a checkbox on the user interface was checked when a form was submitted.
|
validates_acceptance_of :terms_of_service
|
|
How does validates_acceptance_of :field work with your db?
|
‘acceptance’ does not need to be recorded anywhere in your database (if you don’t have a field for it, the helper will just create a virtual attribute).
|
|
How to specify a custom message in validations?
|
:message option
|
|
How to check if associated objects are validated?
|
validates_associated :books
. When you try to save your object, valid? will be called upon each one of the associated objects. |
|
Why should you not use validates_associated on both ends of your associations,?
|
they would call each other in an infinite loop.
|
|
What helper when you have two text fields that should receive exactly the same content.
|
validates_confirmation_of :email
|
|
What field name does validates_confirmation_of :email expect?
|
irtual attribute whose name is the name of the field that has to be confirmed with “_confirmation” appended.
thus email_confirmation |
|
In what case is the validations_confirmation_of not run?
|
when email_confirmation is nil
[to enforce add v_p_o :email_confirmation |
|
validates that the attributes’ values are not included in a given set.
|
validates_exclusion_of :subdomain, :in => %w(www),
|
|
validates_exclusion_of helper, what option receives the set of values which won't be accepted
|
:in => %w(www)
|
|
validates the attributes’ values by testing whether they match a given regular expression,
|
validates_format_of :legacy_code, :with => /\A[a-zA-Z]+\z/
|
|
with validations_format_of, what option receives the regex to validate against
|
:with => /\A[a-zA-Z]+\z/,
|
|
validates that the attributes’ values are included in a given set (opposite of validations_exclusion_of)
|
validates_inclusion_of :size, :in => %w(small medium large)
|
|
validates the length of the attributes’ values
|
validates_length_of :name, :minimum => 2
|
|
how to require at validations an exact length for an input?
|
validates_length_of :registration_number, :is => 6
|
|
how to require at validations a minimum length for an input?
|
validates_length_of :bio, :maximum => 500
|
|
how to require at validations a maximum length for an input?
|
validates_length_of :bio, :maximum => 500
|
|
how to require at validations a range for an input?
|
validates_length_of :password, :in => 6..20
|
|
In validates_lenth)of what is used as a placeholder for the number corresponding to the length constraint being used.
|
%{count}
:too_long => "%{count} characters is the maximum allowed" |
|
validates_size_of is an alias for
|
validates_length_of
|
|
validates that your attributes have only numeric value
|
validates_numericality_of
|
|
How to make sure only whole numbers?
|
validate_numericality of :field, :only_integer => true
|
|
How to ensure only odd numbers are entered?
|
validates_numericality_of :points, :odd => true
|
|
How to ensure only points greater than 10 are entered?
|
validates_numericality_of :points, :greater_than => 10
|
|
How to ensure points less than 40 are entered?
|
validates_numericality_of :points, :less_than => 40
|
|
How to ensure points exactly equal to 4 are entered?
|
validates_numericality_of :points, :equal_to => 4
|
|
How to ensure points greater than or equal to 23 are entered?
|
validates_numericality_of :points greater_than_or_equal_to => 23
|
|
validates that the specified attributes are not empty
|
validates_presence_of :name, :login, :email
|
|
blank? (which is used in validates presence of) checks if the value is either
|
nil or a blank string
|
|
ou want to be sure that an association is present, you’ll need to test whether the
|
foreign key used to map the association is present, and not the associated object itself.
validates_presence_of :order_id |
|
validates that the attribute’s value is unique right before the object gets saved
|
validates_uniqueness_of :email
|
|
How does validates_uniqueness_of work?
|
e validation happens by performing a SQL query into the model’s table, searching for an existing record with the same value in that attribute
|
|
What step should you also take in using validates_uniqueness_of to protect against having two dif db connectsion making two records with same value you intend to be unique?
|
create a unique index in your db
|
|
In validates_uniqueness_of how do you specify other attributes that are used to limit the uniqueness check:
|
set a scope option
validates_uniqueness_of :name, :scope => :year, |
|
In validates_uniqueness_of how do you define whether the uniqueness constraint will be case sensitive or no
|
validates_uniqueness_of :name, :case_sensitive => false
|
|
default setting of validates_uniqueness_of case sensitivity option
|
true - i.e. it is case sensitive
|
|
How to define a custom validator
|
validates_with GoodnessValidator
#where goodness validator inherits from ActiveRecord::Validator class within which a validate method is defined |
|
What class do validators inherit from?
|
class GoodnessValidator < ActiveRecord::Validator
|
|
How do custom validators made with validates_with access the original AR object
|
the record variable
def validate if record.first_name == "Evil" record.errors[:base] << "This person is evil" end |
|
How to add custom errors within a custom validation
|
record.errors[:base] << "This person is evil" end
|
|
How to specify when a validation is run with a block rather than a separate validation class?
|
validates_each
validates_each :name, :surname do |model, attr, value| model.errors.add(attr, 'must start with upper case') if value =~ /\A[a-z]/ |
|
skips the validation when the value being validated is nil
|
:allow_nil => true
validates_inclusion_of :size, :in => %w(small medium large), :allow_nil => true |
|
skips the validation when the value being validated is nil OR AN EMPTY STRING
|
:allow_blank => true
validates_length_of :title, :is => 5, :allow_blank => true |
|
validation only run on create
|
validates_uniqueness_of :email, :on => :create
|
|
validation only runs on update
|
validates_numericality_of :age, :on => :update
|
|
validation only runs on save
|
validates_presence_of :name, :on => :save
|
|
how to make a validation happen only conditionally
|
using :if or :unless options
|
|
specify when the validation should happen.
|
validates_presence_of :card_number, :if => :paid_with_card?
|
|
specify when the validation should not happen
|
validates_presence_of :card_number, :unless => :paid_with_cash?
|
|
:if and :unless validation options take what three values
|
symbols (which point to other methods defined below)
strings (which contain Ruby code which will be called with Eval) Procs |
|
how to use a string to require that a vaidation only runs if name is nil
|
validates_presence_of :surname, :if => "name.nil?"
|
|
how to pass a proc to a validation condition
|
validates_confirmation_of :password, :unless => Proc.new { |a| a.password.blank? }
|
|
how to run chains of custom validations
|
#call validate with symbols of each of the custom validation methods
validate :expiration_date_cannot_be_in_the_past, :discount_cannot_be_greater_than_total_value |
|
how to add custom errors within custom validations?
|
#errors.add(:field, "message")
errors.add(:discount, "can't be greater than") if .... |
|
How to acess the field in a custom validation
|
Use the field name as is. For example if expiration date
errors.add(...) if expiration_date < Date.today |
|
Custom validations are .... to a particular field name
|
not tied - thus they can access any of the field names (or multiple fields)
|
|
How to create your own validation helpers (e.g. validates_choice_of :field)
|
ActiveRecord::Base.class_eval do
def self.validates_as_choice (attr_name, n, options={}) .... end end |
|
In creating custom validation helpers where does the helper name appear
|
def self.helper_name
e.g. def self.validates_as_choice |
|
within what block do you define custom validation helpers
|
ActiveRecord::Base.class_eval do
|
|
How to uninstall all older versions of gems
|
gem cleanup
|
|
where has the error_messages or error_messages_for helper method gone in rails3?
|
out of core, into a plugin called dynamic_form
reasoning - most people want to customize how error messages are displayed |
|
why you probably won't need error_messages helpers anymore?
|
as now they are shown in plain html and are easily formatted. - you can always pull them into a partial (shared/error_messages)
|
|
how to put error messages generated stuff into a partial
|
render "shared/error_messages", :target => @user
then use target within the partial #note - 1 render doesn't require partial 2 the partial name doesnt need to be preceded by _ when called here 3 a @user object can be passed directly |
|
how to get an array of validators on a given model from the console
|
Model.validators
User.validators |
|
how to get an array of validators on a specific trait of a given model from the console
|
Model.validators_on(:attr)
User.validators_on(:email) |
|
code to check if a presence of validator is on a given trait
|
@user.class.validators_on(:email).map(&:class).include? ActiveModel::Validations::PresenceValidator
|
|
how can you express this more concisely
validates_presence_of :email validates_uniqueness_of :email validates_format_of :email |
#validates :attr, :validator => true, :validator2 => true, :validator3 => {hash of options}
validates :email, :presence => true, :uniqueness => true, :format => {:with => //} |
|
where would you store a custom validator
|
in the lib folder
|
|
what class does a custom validator inherir from
|
ActiveModel::EachValidator
|
|
What method does a class inheriting from ActiveModel::EachValidator expect you to define?
|
validate_each
|
|
what args does validate_each require
|
(object, attribute, value)
|
|
how to add an error to an object within the validates_each method?
|
objects.errors[attribute] << "msg" if value != //
|
|
How to include a constant in a model somewhere else in the rails app
|
Modelname::Constant
NOT MODELNAME::CONSTANT |
|
How to default to blank in a select box or date helper
|
:include_blank => true
|
|
How to set the order of day/month/year in a date select helper
|
#the order option which takes an array of day month year
f.date_select :start_date, :order => [:day, :month, :year] |
|
How to exclude day (etc.) in a date select helper
|
#set :discard_day => true
f.date_select :start_date, :discard_day => true |
|
How to go back to previous version of a migration
|
rake db:rollback
|
|
what is named scope know as in rails 3
|
scope - its rebuilt on the new AR Relation class (where, order etc.)
No longer are they a slightly different construct than your normal query methods. They are now built upon the very same query methods that you would use were you to execute a query directly. |
|
what is the lambda's purpose here:
scope :published, lambda { where("posts.published_at IS NOT NULL AND posts.published_at <= ?", Time.zone.now) } } |
delays evaluation of the Time.zone.now argument until when the scope is invoked (otherwise time used would be that when CLASS was first evaluated not scope itself)
|
|
Scope for posts published (i.e. published date greater than now)
|
scope :published, lambda {
where("posts.published_at <= ?", Time.zone.now) } #note - first param is scope name # second param is a lambda which takes { } with conditions inside |
|
within a scope what format do the conditions inside a lambda take
|
ar_word("table.column <= ?", substitue for question)
lambda { where("posts.published_at <= ?", Time.zone.now) } |
|
within a scope how to make sure something is not a null value
|
where("posts.published_at IS NOT NULL AND .....")
|
|
how to get a scope to order by posts published at date?
|
scope :recent, order("posts.published_at DESC")
|
|
what feature of scopes does this show:
scope :recent, published.order("posts.published_at DESC") #note that published is a scope defined already above |
the chainability of scopes within scope definitions
#note how the predefined scope is used in the second param and then new query scopes are chained to it |
|
what feature does this code show?
class Post < ActiveRecord::Base class << self def search(q) query = "%#{q}%" where("posts.title LIKE ?", query).where("posts.body LIKE ?", query) end end end |
creating a method (rather than a scope) which uses the AR scope query language and can be chained to scopes
now you can do queries like: Post.search('w').order('created_at DESC').limit(2).published |
|
how do you do a cross model scope - e.g. User model - all users who have commented on a post
|
#use the joins query stuff
scope :commented, joins(:comments).group("users.id") |
|
what is the format of a joins query (SQL)
|
join table1 on table1.column_name= table1.column_name - where column_name is often id
joins("join comments on comments.user_id = users.id") |
|
How do you get an array of a certain attribute of a model across many models?
e.g. the view_count for all posts |
Post.collect(&:view_count)
#note 1 use of the collect method #note 2 & then : then attrib_name |
|
How to perform an action on a set of models found with a scope? - e.g. increment the views count on all publichsed Posts
|
Post.published.update_all("views_count = views_count + 1")
#call update_all on the scoped set #update_all takes a string which will be evaled to logic #update all takes one of the attrs in it's logic |
|
How to destroy all unpublisehd posts (where unpublished is just a scope)
|
Post.unpublished.destroy_all
|
|
How to build objects from a given scope?
E.g. build psots with title Luda here scope :titled_luda, where(:title => 'Luda') |
Post.titled_luda.build
#thus scopes are now both packages of query and constructino logic |
|
which one of these will not work in builder methods?
scope :titled_luda, where(:title => 'Luda') scope :title_luda, where("title = 'Luda'") |
the second one - you must always use the hash form of where for builders to work
where(:title => "luda") |
|
How to find all Users in order of descending user id
|
#order(tablename.id DESC)
# note the space between the table.col and DESC or ASC User.order('users.id DESC') |
|
How to modify all shirt items so their color attr is now black?
|
Shirt.update_all :colour => 'black'
|
|
How to create a scope which takes a time variable and finds the items published since then
Item.since(time) |
scope :since, lambda {|time| where("created_at > ?", time)}
#note use of lamba {|var| where(" ?", var) } structure |
|
Whats wrong with this is rails 3
scope :since, lambda {|time| {:conditions => ["created_at > ?", time] }} |
options hash will be deprecated in Rails 3.1 (i.e. the {:conditions shit}
replace with where() clause etc. |
|
In Rails 3, the Application itself, the router, and controller actions themselves are all .... applications.
|
rack
#thus you can also insert standard Rack middleware in config.ru, in your Rails application, in the router, or even in a controller’s action |
|
ActionController and ActionMailer to inherit from a common superclass: ....
|
AbstractController.
#This means that ActionMailer can no longer drift away from ActionController, leaving us with two distant cousin APIs. |
|
Rails 3..... allowing developers to convert Strings into safe Strings easily
|
escapes all Strings,
thus no need to worry about XSS protection as before |
|
what does integrating ntegrating Nick Kallen’s ActiveRelation codebase mean?
|
you can chain queries for refinement before Rails builds the actual SQL query.
For instance, instead of Post.scoped immediately connecting to the database and retrieving all posts, it creates a relation object representing the idea of “all posts”. You can then refine further, such as Post.scoped.where(:author => "Yehuda"). This means that you can pass around relations, refining them as appropriate in helper methods before the view finally kicks off the query when it iterates over the objects. |
|
A Rails 3 application is an object (of the class
|
Rails::Application
#also doubles as a valid Rack application |
|
adding a member or collection to a resouce gives you what
|
a url helper method of the format
method_name_model_name_path e.g. preview_photo_path |
|
when creating custom validation methods what are the alternatives to plain old validate :method_name
|
validate_on_create or validate_on_update
|
|
If you were to create a validator helper (which inherits from ActiveRecord::Base) where woud you put it?
|
in config/initializers.
|
|
How to add errors messages that are related to the object’s state as a whole, instead of being related to a specific attribute
|
errors.add_to_base("This person is invalid because ...")
|
|
What params does errors.add_to_base have?
|
only one - the message to be displaye
|
|
How to add error messages that are related to particular attribute
|
errors.add(:name, "cannot contain the characters !@#%*()_-+=")
|
|
What params does errors.add take?
|
two
first - :attr_name second - msg |
|
How to see the errors on a particular attribute
|
person.errors.on(:name) # => "cannot contain the characters !@#%*()_-+="
|
|
How to see the errors on a particular attribute as seen in the form displayed to a user (ie. attr name appeneded)
|
person.errors.full_messages # => ["Name cannot contain the characters !@#%*()_-+="]
|
|
person.errors.on(:name) returns what if there are no errors?
|
nil
|
|
adding a member or collection to a resouce gives you what
|
a url helper method of the format
method_name_model_name_path e.g. preview_photo_path |
|
when creating custom validation methods what are the alternatives to plain old validate :method_name
|
validate_on_create or validate_on_update
|
|
If you were to create a validator helper (which inherits from ActiveRecord::Base) where woud you put it?
|
in config/initializers.
|
|
How to add errors messages that are related to the object’s state as a whole, instead of being related to a specific attribute
|
errors.add_to_base("This person is invalid because ...")
|
|
What params does errors.add_to_base have?
|
only one - the message to be displaye
|
|
How to add error messages that are related to particular attribute
|
errors.add(:name, "cannot contain the characters !@#%*()_-+=")
|
|
What params does errors.add take?
|
two
first - :attr_name second - msg |
|
How to see the errors on a particular attribute
|
person.errors.on(:name) # => "cannot contain the characters !@#%*()_-+="
|
|
How to see the errors on a particular attribute as seen in the form displayed to a user (ie. attr name appeneded)
|
person.errors.full_messages # => ["Name cannot contain the characters !@#%*()_-+="]
|
|
person.errors.on(:name) returns what if there are no errors?
|
nil
|
|
person.errors.on(:name) returns what if there are multiple errors?
|
an array of errors
|
|
How do you intentionally want to clear all the messages in the errors collection.
|
person.errors.clear
|
|
calling errors.clear upon an invalid object won’t .....
|
actually make it valid: the errors collection will now be empty, but the next time you call valid? or any method that tries to save this object to the database, the validations will run again
|
|
returns the total number of error messages for the object.
|
person.errors.size # => 3
|
|
What are callbacks
|
methods that get called at certain moments of an object’s lifecycl
|
|
what are the two ways to register callbacks
|
before_validation :ensure_login_has_a_value
#where there is a private method with this name before_create {|user| user.name = user.login.capitalize if user.name.blank?} #use a block for one liners |
|
callback before save
|
before_save
|
|
callback after save
|
after_save
|
|
callback after update
|
after_update
|
|
callback before update
|
before_update
|
|
callback before destroying an object
|
before_destroy
|
|
callback after destroying an object
|
after_destroy
|
|
callback before validations
|
before_validation
|
|
Callback will be called whenever an Active Record object is instantiated, either by directly using new or when a record is loaded from the database.
|
after_initialize
|
|
callback will be called whenever Active Record loads a record from the database.
|
after_find
|
|
Note that after_initialize and after_find will both ....
|
significantly slow down the queries as they will both be called for each record found in the database
|
|
give examples of methods which trigger the after_find callback
|
all, first, find find_by_attr, last
|
|
what update action skips callbacks
|
update_all
#note that update and update_attributes and update_attributes(!) all run callbacks |
|
what delete action skips callbacks
|
# delete
# delete_all #note that destroy, destroy_all all run callbacks |
|
what is the execution chain?
|
all your model’s validations, the registered callbacks, and the database operation to be executed.
|
|
If any before callback method returns exactly false or raises an exception
|
the execution chain gets halted and a ROLLBACK is issued
|
|
What happens if you have an after destroy method in posts and destroy a user (which has many dependent =>destroy posts)
|
the after_destroy in the post method is called
|
|
how to make the running of callbacks conditional?
|
using the :if and :unless options, which can take a symbol, a string or a Proc
#just like validations |
|
give an example of a before_save callback conditional on a proc which requires order be paid by hard
|
before_save :normalize_card_number, :if => Proc.new { |order| order.paid_with_card? } end
|
|
When writing conditional callbacks, it’s possible to mix
|
both :if and :unless in the same callback declaration.
after_create :send_email_to_author, :if => :author_wants_emails?, :unless => Proc.new { |comment| comment.post.ignore_comments? } |
|
If callback methods that you’ll write will be useful enough to be reused by other models how do you do so?
|
#create a class ModelCallbacks
# def the callbacks (may take the object as a param) #call the ModelCallback.new in the callback register class PictureFileCallbacks def after_destroy(picture_file) File.delete(picture_file.filepath) if File.exists?(picture_file.filepath) end end #in PictureFile class after_destroy PictureFileCallbacks.new |
|
why use observers instead of callbacks?
|
allow you to add the same functionality outside of a model. For example, it could be argued that a User model should not include code to send registration confirmation emails.
|
|
magine a User model where we want to send an email every time a new user is created. Because sending emails is not directly related to our model’s purpose, we could create an observer to contain this functionality.
|
class UserObserver < ActiveRecord::Observer
def after_create(model) # code to send confirmation email... end end |
|
Where are Observers are conventionally placed .....
|
app/models directory
|
|
for observers to work what else must be done
|
they must be egistered in your application’s config/environment.rb file
config.active_record.observers = :user_observer |
|
How can single observers be used to add behaviour to more than one model
|
class MailerObserver < ActiveRecord::Observer
observe :registration, :user #note that this observe macro style method is not necessary if only one model is being observed as Rails will strip the model from the class name |
|
should controllers have singular or plural names?
|
plural
emails_controller #not email_controller |
|
How to format a date object in a Rails view?
|
.strftime('%B %Y')
#%B = month %Y = year |
|
Action Pack is single gem which contains ....
|
Action Controller, Action View and Action Dispatch. The “VC” part of “MVC”.
|
|
Services provided by Action Controller include ....
|
session management, template rendering, and redirect management.
|
|
Action View manages ...
|
rendering templates, including nested and partial templates, and includes built-in AJAX support.
|
|
Action Dispatch handles routing of ....
|
web requests and dispatches them as you want, either to your application or any other Rack application
|
|
Active Model provides a ..
|
defined interface between the Action Pack gem services and Object Relationship Mapping gems such as Active Record
...allows Rails to utilize other ORM frameworks in place of Active Record if your application needs this. |
|
Active Record is ...
|
provides database independence, basic CRUD functionality, advanced finding capabilities, and the ability to relate models to one another, among other services.
|
|
Active Resource provides ....
|
a framework for managing the connection between business objects and RESTful web service
map web-based resources to local objects with CRUD semantics. |
|
Active Support is a ...
|
collection of utility classes and standard Ruby library extensions that are used in the Rails, both by the core code and by your applications.
|
|
Railties is
|
code that builds new Rails applications and glues the various frameworks and plugins together in any Rails application.
|
|
how to install Rails
|
gem install rails
#through rubygems |
|
HOw to start a Rails application called blog?
|
$ rails new blog
|
|
Action Controller ....
|
processes incoming requests to a Rails application, extracts parameters, and dispatches them to the intended action.
|
|
In what file do you tell others what your application does, how to set it up, and so on.
|
README.rdoc
|
|
how to install all gems on a new application
|
bundle install
|
|
how to create a db with Rails
|
$ rake db:create
|
|
when you run rails server where will you see your app running in the browser?
|
http://localhost:3000.
|
|
how to run a migration
|
$ rake db:migrate
|
|
why do migration files include timestamps?
|
to ensure that they’re processed in the order that they were created.
|
|
Models inherit from what class?
|
ActiveRecord::Base
#gives it basic database CRUD (Create, Read, Update, Destroy) operations, data validation, as well as sophisticated search support and the ability to relate multiple models to one another. |
|
Migrations inherit from what class?
|
ActiveRecord::Migration
|
|
How to create a Post with content attr "A New Post!"
|
Post.create(:content => "A new post")
|
|
diff between console and develpoemnt web server
|
console does not automatically load your code afresh for each line. If you make changes to your models while the console is open, type reload! at the console prompt to load them
|
|
Rails 3 auto escapes HTML - how to get unescaped stuff?
|
<%= raw post.name %>.
|
|
how to call a form partial from within a new view file (@post defined)
|
<%= render 'form' %>
#@post can be used in the partial now since partials receives all the instance variables defined in the calling view file, |
|
how to instantiate a new Post object from the data supplied by the user on the form, which Rails makes available in the params hash.
|
Post.new(params[:post])
|
|
how to redirect to showing an indiv post
|
redirect_to(@post)
|
|
how to re-render the new action
|
render :action => "new"
|
|
how to find an individual post for showing or editing
posts/1 |
@post = Post.find(params[:id])
|
|
how to update a post with supplied params attributes
|
@post.update_attributes(params[:post])
|
|
to where should you redirect after @post.destroy in a controller destroy action
|
the index since there isn't any record to display
redirect_to(posts_url) |
|
what sets up a foreign key column for the association between the two model
|
other_model:references
#in migration t.references :other_model |
|
what appears in the model which has the foreign_key column
|
belongs_to :post
|
|
in routes how do you capturing the hierarchical relationship that exists between posts and comments.
|
resources :posts do
resources :comments end |
|
What do most controllers inherit from?
|
ApplicationController
|
|
how to create comments on a post variable (in the comments controller)
|
#find the relevant post, call its comments, and call c reate on that using the params hash - will auto link the comment so it belongs to a particular post
@post = Post.find(params[:post_id]) @comment = @post.comments.create(params[:comment]) |
|
what will the form for a post's comment look like
|
#in a post show file - not the array in the form_for with the post var and the building of comments
<%= form_for([@post, @post.comments.build]) do |f| %> |
|
how to render a collection of partials for all the comments associated with a given post
|
<%= render :partial => "comments/comment", :collection => @post.comments %>
|
|
ou delete a post then it’s associated comments will also need to be deleted - how to do this
|
#WiTHIN the posts file
has_many :comments, :dependent => :destroy #put dependent=> destroy in the declaration of the association with the other model ( |
|
How to assign a section in database.yml file to a variable (details)
|
# &variable_name straight after server type declaration
development: &details database: sql etc. production: .... |
|
How to reuse a variable in a section in database.yml (details)
|
# <<: *variablename under the inheriting server type declaration
production: <<: *details |
|
how to avoid a NoMethodError in a view
e.g. age of a person variable |
@person.try(:age)
|
|
when you are generating a model which has another models foreign key what do you say
|
#other_model_name(singular):references
r g model tag post:references |
|
how to accept attributes for another model (e.g. tags) from within a post form (code thats needed in the model)
|
accepts_nested_attributes_for :tags
|
|
in a post model which accepts nested attributes for tags how to prevents saving new tags that do not have any attributes filled in.
|
#pass a reject_if option with a proc looking at whether the attributes are black
accepts_nested_attributes_for :tags, :reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } } |
|
how to ensure there is a tag object ready on a post form (for nested attributes)
|
@post.tags.build
|
|
view helpers provide ...
|
small snippets of reusable code for views
|
|
what comes at the top of a helper (e.g. posts_helper)
|
module PostsHelper
#so its a module not a class |
|
give an example of a helper which accepts a post object
how do you call it |
def join_tags(post)
post.tags.map { |t| t.name }.join(", ") end #call with <%= join_tags(@post) %> |
|
. The application object (which every Rails 3 app must have) is defined in ...
|
config/application.rb
#contains lots of old environment.rb stuff |
|
what plugin automates part of the Rails 3 upgrade process
|
Rails Upgrade - call rails:upgrade:check to run (can generate Gemfile)
|
|
how to start a Rails 3 application (given that they have their own name space)
|
YourAppName.boot
|
|
entral repository of all sorts of Rails wide configuration options.
|
Rails.config object
|
|
what has been added to the Root path
|
Rails.root/app
|
|
Rails Generators API was merged with what ...
|
Rails templates API
|
|
where to place files to override templates in generators
|
Rails.root/lib/templates.
|
|
view the routes for one controller.
|
rake routes CONTROLLER=x
|
|
RAILS_ENV is now
|
Rails.env
|
|
RAILS_ROOT is now
|
Rails.root
|
|
is protect_from_forgery on or off by default in Rails 3
|
protect_from_forgery is on by default (in application_controller.rb)
|
|
defaults for session store are stored where?
|
config/initializers/session_store.r
|
|
How to set encrypted values in cookies
|
cookie.secure[:key] => value.
|
|
# Instead of: ActionController::Routing::Routes.draw do |map| map.resources :posts end
# You do: |
AppName::Application.routes do resources :posts end
#notes # 1 AppName namespacing # 2 lack of map - just put resources |
|
Rails router is now ...
|
rack_mount with a Rails DSL
|
|
how to make a form use AJAX
|
form_for @post, :remote => true
|
|
form_for is called in what different way now?
|
<%= form_for @post do |f| %>
#needs <%= instead of just <% |
|
what awesome new attribute based validation shortcut method does Rails 3 introduce?
|
validates :attribute, options_hash
|
|
how are options such as presence, uniquenss and acceptance used in the
validates :attribute, options_hash shortcut |
# :presence => Boolean.
|
|
how are options such as exclusion and inclusion used in the
validates :attribute, options_hash shortcut |
# :exclusion => { :in => Ennumerable }.
# :inclusion => { :in => Ennumerable }. #note the subhash using :in |
|
What filename does bundler use?
|
Gemfile
|
|
how to add a gem to your app in the gemfile (basic formula with version)
|
gem "gem_name", "version"
gem "haml", "1.8.6" #notice the quotes around gem version |
|
how to specify a gem should be greater than a certain version
|
gem "haml", "> 1.8.6"
|
|
how to specify a gem should have a dif name than defaul in require_env call
|
gem "name", "version", :require_as =>"file"
gem "sqlite3", "13". :require => "sq-slite" |
|
how to specify where in git a gem is to be found
|
gem "name", "version", :git => "git://github.com/wycats/thor":
|
|
how to specify a gem should only run in certain environments
|
e.g. group :development do
gem "rails" end #only block #use only |
|
how to specify an original gem only runs in production
|
gem "foo", :group => :production
#contrast this to the block group method |
|
how to install gems using bundler
|
bundle install
|
|
what does bundle lock do
|
When you're ready to share your application or deploy it, lock down all the versions of the gems you're using so there is no inconsistencies on deploy
|
|
how to use a gem you are actively developing on your machine?
|
gem "nokogiri", :path => "~/Code/nokogiri"
#specify the path variable |
|
how to install all dependencies expect those in specified groups
|
$ bundle install --without test
|
|
how to specify a gem should use a particular branch on git
|
gem "rails", :git => "git://github.com/rails/rails.git", :branch => "2-3-stable"
|
|
.bundle folder is ..
|
specific to each machine -- thus should be gitignored
|
|
how to specify a gem dependency in multiple groups
|
ou can place a dependency in multiple groups at once as well
group :development, :test do gem "wirble" gem "ruby-debug" end |
|
After locking your dependencies you may not modify the Gemfile without unlocking first - what do you type?
|
bundle unlock
|
|
how to save without validating (previously save(false))
|
save(:validate => false)
|
|
scope whereby you check for models created later than a certain (variable) date
|
scope :since, lambda {|time| where(“created_at > ?”, time)
|
|
what function is used to format date and time in ruby?
|
strftime function
Time.now().strftime(“%d/%m/%y %H:%M”) |
|
what strftime option (placed inside the quotes insides the bracketed params to the function) gives you:
August |
%B
|
|
what strftime option (placed inside the quotes insides the bracketed params to the function) gives you:
20 (date) |
%e
|
|
what strftime option (placed inside the quotes insides the bracketed params to the function) gives you:
2008 |
%Y
|
|
what strftime option (placed inside the quotes insides the bracketed params to the function) gives you:
Aug |
%b
|
|
what strftime option (placed inside the quotes insides the bracketed params to the function) gives you:
08 (month) |
%m
|
|
what strftime option (placed inside the quotes insides the bracketed params to the function) gives you:
16 (hours on 24 clcok) |
%H
|
|
what strftime option (placed inside the quotes insides the bracketed params to the function) gives you:
56(minutes) |
%M
|
|
what strftime option (placed inside the quotes insides the bracketed params to the function) gives you:
21 (seconds) |
%S
|
|
what strftime option (placed inside the quotes insides the bracketed params to the function) gives you:
11 (hour of day on 12 hour clock |
%I
|
|
what strftime option (placed inside the quotes insides the bracketed params to the function) gives you:
am / pm |
%p
|
|
what strftime option (placed inside the quotes insides the bracketed params to the function) gives you:
Sun (abbreviated weekday name) |
%a
|
|
what strftime option (placed inside the quotes insides the bracketed params to the function) gives you:
Sunday (full weekday name) |
%A
|
|
what strftime option (placed inside the quotes insides the bracketed params to the function) gives you:
GMT (time zone name) |
%Z
|
|
what strftime option (placed inside the quotes insides the bracketed params to the function) gives you:
98 (year without the century) |
%y
|
|
Time.now - 10 gives what
|
10 seconds ago
#simple arithmetic is in seconds with time objects |
|
what's the date equivalent of Time.now
|
Date.today
|
|
Date.today + 1 gives what
|
1 day later
#simple arithmetic is in days with date objects |
|
how to create a table in a migrtion
|
def self.up
create_table :products do |t| t. |
|
what col comes for free in migrations
|
primary key
|
|
how to fix bad data in a migration
|
User.update_all ["receive_newsletter = ?", true]
#done outside / after the change_table part but before self.up has ended |
|
how are migration files named
|
YYYYMMDDHHMMSS_create_products.rb, that is to say a UTC timestamp identifying the migration followed by an underscore followed by the name of the migration
|
|
what naming convention must you remember with migrations
|
The name of the migration class (CamelCased version) should match the latter part of the file name.
0080906120000_create_products.rb should define CreateProducts |
|
what to do if you messed up your previous migration (if migration only run on dev machine)
|
rollback the migration (for example with rake db:rollback), edit your migration and then run rake db:migrate to run the corrected version.
|
|
what to do if you messed up your previous migration (if migration run on production)
|
write a new migration that performs the changes you require.
|
|
default format of rails model generator cmd
|
rails generate model Product name:string description:text
#model name is capitalized #name of column comes before data type |
|
what special cmd line format creates a migration containing the appropriate add_column and remove_column statements will be created.
|
“AddXXXToYYY” or “RemoveXXXFromYYY” and is followed by a list of column names and type
rails generate migration AddPartNumberToProducts part_number:string |
|
if you don’t want a primary key at all (for example for a HABTM join table) you can pass
|
:id => false
create_table firm_solicitors, :id => false do |t| |
|
what close cousing of create_table is used to change_tables
|
change_table :products do |t|
t.remove :description, :name end |
|
how to add a string column within a change_table blcok
|
t.string :part_number
#same as create table syntax |
|
how to rename a column in a change table block
|
t.rename :upccode, :upc_code
|
|
how to create a category_id column of the appropriate type on the products table
|
create_table :products do |t|
t.references :category end #Note that you pass the model name, not the column name. |
|
how to output code in a model to the log?
|
logger.debug "#{@months_histogram.values.inspect}"
|
|
how to create an attachment_id col and a attachment_type column with a default of 'photo'
|
t.references :attachment, :polymorphic => {:default => 'Photo'}
|
|
how to run sql commands from a migration
|
#being with execute <<-SQL
# end with SQL execute <<-SQL ALTER TABLE products ADD CONSTRAINT fk_products_categories FOREIGN KEY (category_id) REFERENCES categories(id) SQL |
|
what does the error IrreversibleMigration mean
|
raised when you are trying to run a down migration but you can' t reverse a migration - e.g. destroyed data
|
|
db:migrate does what
|
runs the up for all migrations not yet run
|
|
running the db:migrate also invokes the
|
db:schema:dump task,
|
|
db:schema:dump task doew what
|
update your db/schema.rb file to match the structure of your database.
|
|
to migrate to version 20080906120000 run
|
rake db:migrate VERSION=20080906120000
|
|
go to previous migration
|
rake db:rollback
|
|
go back 3 migrations
|
rake db:rollback STEP=3
#step param with rollback #note that params are capitalized and use equals signs |
|
doing a rollback and then migrating back up again.
|
db:migrate:redo
|
|
drop the database, recreate it and load the current schema into it.
|
db:reset
|
|
If you need to run a SINGLE specific migration up or down
|
db:migrate:up and db:migrate:down
#Just specify the appropriate version rake db:migrate:up VERSION=20080906120000 |
|
within a migrate up or down how do you get terminal outpu of "created a table lol!"
|
say "Created a table lol"
|
|
suppresses any output messages generated by its block in migrations
|
#run the methods in a suppress_messages blcok
suppress_messages do create_table :products do |t| t.string :name end |
|
If you just want Active Record to shut up when running migrations ...
|
rake db:migrate VERBOSE=false
|
|
If you add a column to a table in a migration and then try and use the corresponding model to insert a new row it may try to use the old column information - due to caching info about cols of a model.
How to get past this (w/in migration) |
#Model.reset_column_information
add_column :product, :part_number, :string Product.reset_column_information |
|
Migrations, mighty as they may be, are not the authoritative source for your database schema..... what is?
|
db/schema.rb
#not designed to be edited |
|
There is no need (and it is error prone) to deploy a new instance of an app by replaying the entire migration history. It is much simpler and faster to ...
|
ust load into the database a description of the current schema.
|
|
How to change the schema format setting
|
#environment.rb file
config.active_record.schema_format :sql or :ruby. |
|
When should you set the schema format to :sql.
|
db/schema.rb cannot express database specific items such as foreign key constraints, triggers or stored procedures. While in a migration you can execute custom SQL statements, the schema dumper cannot reconstitute those statements from the database. If you are using features like this
|
|
The Active Record way claims that intelligence belongs in your ..... not in your ........
|
modesl - not the database
As such, features such as triggers or foreign key constraints, which push some of that intelligence back into the database, are not heavily used. |
|
In a view how do you get a yaml form of an object
|
#pass debug then the object
<%= debug @post %> |
|
In a view how do you get a yaml form of an instance var, method or object
|
# to_yaml
<%= @post.to_yaml %> |
|
when working with arrays or hashes how do you view somethig (for debugging) in a view
|
#inspect
<%= [1, 2, 3, 4, 5].inspect %> |
|
activate Rails built-in support to debug RJS,
|
in the Rails::Initializer do |config| block inside environment.rb:
config.action_view[:debug_rjs] = true |
|
How many log files does Rails use?
|
Rails maintains a separate log file for each runtime environment.
|
|
HOw to specify an alternative logger (eg. Log4R)
|
#in any environment file
ActiveRecord::Base.logger = Log4r::Logger.new("Application Log") # In any initialzier config.logger = Log4r::Logger.new("Application Log") |
|
default log file name is ...
|
environment_name.log.
|
|
see current log level
|
ActiveRecord::Base.logger.level
|
|
What log levels are available?
|
:debug, :info, :warn, :error, and :fatal
|
|
How to change the default log level, use
|
# In any environment initializer
#look how you use the Logger::LEVEL syntax (following a config.log_level) config.log_level = Logger::WARN |
|
default Rails log level in production
|
info [1]
|
|
default Rails log level in test / dev
|
test [0]
|
|
To write in the current log ....
|
use the logger.(debug|info|warn|error|fatal) method from within a controller, model or mailer
logger.debug "Person attributes hash: #{@person.attributes.inspect}" |
|
住民
|
주민
residents, inhabitants [reside + people] |
|
The debugger used by Rails, ruby-debug, comes
|
as a gem
gem install ruby-debug |
|
nside any Rails application you can invoke the debugger by calling the ...
|
debugger method.
def new debugger @person = Person.new end |
|
what does this message in the logs mean?
***** Debugger requested, but was not available: Start server with --debugger to enable ***** |
you need to restart the server with script/server --debugger
|
|
As soon as your application calls the debugger method ...
|
e debugger will be started in a debugger shell inside the terminal window where you launched your application server, and you will be placed at ruby-debug’s prompt (rdb:n).
|
|
how to get info about available commands in debug mode?
|
help
or help command |
|
how to abbreviate ruby-debug commands
|
by supplying just enough letters to distinguish them from other commands, so you can also use l for the list command.
|
|
list in rdb does what?
|
shows you where you are in the code by printing 10 lines centered around the current line; the current line in this particular case is line 6 and is marked by =>.
|
|
what happens if you press l again whilst already in list
|
the next ten lines of the file will be printed out. - 10 more again, eventually going back up to the beginning of the file
|
|
print the backtrace of the application in rdb mode?
|
backtrace
or where |
|
how to move anywhere you want in a rdb backtrace
|
frame n
#where n is a number, the frame of the backtrace |
|
how to move up and down a backtrace
|
up n
down n |
|
in rdb how do you evaluate something in the current context.
|
just type it!
#@posts = Post.find(:all) |
|
how to get all the instance variables within a context in rdb
|
type
instance_variables #dynamically updated as you execute code |
|
test if an instance variable (@ posts) is available within the current context of code in rdb
|
instance_variables.include? "@posts"
|
|
vost convenient way to show variables and their values:
|
var
|
|
show global vars in rdb
|
var global
v g |
|
show local vars in rdb
|
var local
v l |
|
show instance variables of object in rdb
|
v[ar] i[nstance] <object>
#e.g. var instance Post.new |
|
way of tracking the values of a variable while the execution goes on in rdb
|
display @recent_comments
The variables inside the displaying list will be printed with their values after you move in the stack |
|
如前
|
여전
remain unchanged, be as before, be as (it) used to be, be just as it was. [like, as if + before] |
|
continue running your program until the next logical stopping point and return control to ruby-debug.
|
step
or next |
|
to move forward n steps respectively in rdb
|
step n
|
|
火力
|
화력
caloric (force), heating power, thermal power [fire + power] |
|
how to look at a new post in debugger
|
var instance Post.new
|
|
what does a breakpoint do?
|
makes your application stop whenever a certain point in the program is reached
|
|
add breakpoints dynamically with the command
|
break (or just b)
|
|
set breakpoint in the line in the current source file.
|
break line
e.g. break 10 |
|
command to disable breakpoints (in rdb)
|
disable breakpoint
|
|
list breakpoints.
|
info breakpoints
|
|
To delete breakpoints
|
delete _n_ t
|
|
intercept an exception of type exception-name when there would otherwise be is no handler for it.
|
catch exception-name
(or just cat exception-name) |
|
command in rdb to list all active catch points
|
catch
|
|
resume execution of an application that is stopped in the debugger:
|
continue (or c)
finish (or f) |
|
edit file using the editor specified by the EDITOR environment variable. A specific line can also be given.
|
edit [file:line]
|
|
open the current file in TextMate
|
tmate _n_ (abbreviated tm)
|
|
exit the debugger
|
quit command (q) or exit
|
|
see full list of options in ruby debugger
|
help set
|
|
option to reload source code when changed in ruby debug
|
set reload
|
|
what are memory leaks in a rails app
|
If a Ruby object does not go out of scope, the Ruby Garbage Collector won’t sweep it since it is referenced somewhere - eventually fucks up performance
|
|
library for finding memory leaks in rails
|
bleak_house (gem)
|
|
how to set up your app for memory leak profiling
|
# at the bottom of config/environment.rb:
require 'bleak_house' if ENV['BLEAK_HOUSE'] |
|
how to start a server in bleak house mode
|
RAILS_ENV=production BLEAK_HOUSE=1 ruby-bleak-house rails server
|
|
how many requests should you make to get bleak house a good data sample
|
couple hundred requests
|
|
how to stop Bleak House and produce a dumpfile in /tmp:
|
ctrl c
|
|
what will the bleak house dumpfile show?
|
your 20 leakiest lines of code
|
|
code for creating a new order for a particular customer (both separate models w/ association)
|
@order = @customer.orders.create(:order_date => Time.now)
#notice 1 - customer.orders (plural) calls create # notice 2 create takes as params the attributes of the model being created) |
|
how to require that a customer model destroy all it's related order models when customer.destroy is called
|
has_many :orders, :dependent => :destroy
|
|
class Order < ActiveRecord::Base belongs_to :customer
end what model has a foreign_id column? |
order -> since it must have a way of referencing the model it "belongs to"
|
|
class Order < ActiveRecord::Base belongs_to :customer
end what will the foreign_id col be called |
customer_id
|
|
class Supplier < ActiveRecord::Base has_one :account
end what model has a foreign_id column? |
account ->
#note that this is the opposite to the belongs_to |
|
when should you use a has_one relationship?
|
If A has_one B, then when you create a new A you're probably going to be creating a new B as well.
|
|
class Customer <ActiveRecord::Base
has_many :orders end where does the foreign_id column reside |
orders table -> since many different orders will point to the same customer
|
|
How set up a many-to-many connection between Pysicians and Patients (using appointments)
|
Physicians - hm apps(connecting table), hm patients, :through => apts (connecting table
Appointments - bt physicians, bt patients (bt both tables it connects) Patients (as per physicians) - makes sense since both are equals on opposite sides of the hm_t table |
|
Code to set up a many-to-many connection between Pysicians and Patients (using appointments)
|
class Physician < ActiveRecord::Base
has_many :appointments has_many :patients, :through => :appointments end class Appointment < ActiveRecord::Base belongs_to :physician belongs_to :patient end class Patient < ActiveRecord::Base has_many :appointments has_many :physicians, :through => :appointments end |
|
using a hm through connection with physicians and patients (through appointments) how do you access a physicians pateints
|
physician.patients
|
|
association which indicates that the declaring model can be matched with ONE instance of another model by proceeding through a third model
|
has_one :throug
|
|
code for a has_one :through association
|
#one side has_one of the other and has_one through tht connector, the other belongs_to the first, and has one connector, the connector table belongs to the second
class Supplier < ActiveRecord::Base has_one :account has_one :account_history, :through => :account end class Account <ActiveRecord::Base belongs_to :supplier has_one :account_history end class AccountHistory < ActiveRecord::Base belongs_to :account end |
|
has_and_belongs_to_many usages in models
|
declare the same in both models
class Assembly < ActiveRecord::Base has_and_belongs_to_many :parts end class Part < ActiveRecord::Base has_and_belongs_to_many :assemblies end |
|
creates a direct many-to-many connection with another model, with no intervening model
|
has_and_belongs_to_many
|
|
has_and_belongs_to_many in two models needs how many tables
|
3 tables - a connecting one is needed despite having no mention in AR (i..e. no model file inheriting from AR)
[make sure to add the joining table in the migrations] |
|
you have a Assembly and a Part class which has_and_belong_to - what is the intervening table called
|
assemblies_parts
#lower case plural first table _ lower case plural second table |
|
how to choose Between belongs_to and has_one
|
semantic sense. For example, it makes more sense to say that a supplier owns an account than that an account owns a supplier.
|
|
how to choose between has_many :through and has_and_belongs_to_many?
|
you should set up a has_many :through relationship if you need to work with the relationship model as an independent entity. If you don’t need to do anything with the relationship model, it may be simpler to set up a has_and_belongs_to_many relationship
|
|
how to make a model have a relation to itself? i.e. manager and subordinate employees
|
#has_many :whatever_you_want, :class_name => "Same as file", :foreign_key => same_integer_column_in_the_table
class Employee has_many :subordinates, :class_name => "Employee", :foreign_key => "manager_id" belongs_to :manager, :class_name => "Employee" end |
|
psudeo code for a picture model that belongs to either an employee model or a product model using polymorphic
|
picture model -> :bt => special_poly_name, :polymorphic => true
other models -> hm => pictures (original model), :as => :special_polymorphic_name |
|
code for a picture model that belongs to either an employee model or a product model using polymorphic
|
class Picture
belongs_to :imageable, :polymorphic => true end class Employee has_many :pictures, :as => :imageable end class Product has_many :pictures, :as => :imageable end |
|
if an employee has many picures using polymorphism what code retreives this set
class Employee has_many :pictures, :as => :imageable end |
@employee.pictures
|
|
if an employee has many picures using polymorphism what code finds the parent of the given pic (employee / product)
class Employee has_many :pictures, :as => :imageable end |
@picture.imageable
|
|
to make polymorphism work what do you need in the migrations
|
you need to declare both a foreign key column and a type column in the model that declares the polymorphic interface
so if pictures has polymorphic => true (as imageable) then migration needs these extra columns t.integer :imageable_id t.string :imageable_type |
|
All of the association methods are built around .... which means ....
|
caching / the result of the most recent query available for further operations
customer.orders # retrieves orders from the database customer.orders.size # uses the cached copy of orders customer :-) |
|
if you are using assocation methods and you want to reload the cache, because data might have been changed by some other part of the application? Just
|
Just pass true to the association call:
customer.orders(true).empty? |
|
For belongs_to associations you need to create what in your db / migrations?
|
foreign keys,
|
|
For has_and_belongs_to_many associations you need to create what in your db / migrations?
|
you need to explicitly create the joining table with integer columns of the model_id of each of the two habtm -
primary key should be turned off too create_table :assemblies_parts, :id => false do |t| |
|
how to specify a different join table name than the AR default (
|
:join_table option,
|
|
how does AR make the join table
|
plural of the tables, in lexical order (c before f - although weird stuff can happen as it uses > string ) separated with an underscore
|
|
By default, associations look for objects only within the ....
|
current module’s scope
#here both classes are w/in the business module so can access each other directrly. module Business class Supplier < ActiveRecord::Base has_one :account end class Account < ActiveRecord::Base belongs_to :supplier end end |
|
If a class is declared in a module Biz who do you access it
|
Biz::class-name
thus for the association to work you must declare the class name with the module name space has_one :account, :class_name => "Biz::Account" |