view templates are written in a language called ERB (Embedded Ruby) which is converted by the request cycle in Rails before being sent to the user.
Each action's purpose is to collect information to provide it to a view.
A view's purpose is to display this information in a human readable format.
routing file which holds entries in a special DSL (domain-specific language) that tells Rails how to connect incoming requests to controllers and actions.
You can create, read, update and destroy items for a resource and these operations are referred to as CRUD operations
A controller is simply a class that is defined to inherit from ApplicationController.
If not found, then it will attempt to load a template called application/new. It looks for one here because the PostsController inherits from ApplicationController
:formats specifies the format of template to be served in response. The default format is :html, and so Rails is looking for an HTML template.
:handlers, is telling us what template handlers could be used to render our template.
When you call form_for, you pass it an identifying object for this
form. In this case, it's the symbol :post. This tells the form_for
helper what this form is for.
that the action attribute for the form is pointing at /posts/new
When a form is submitted, the fields of the form are sent to Rails as parameters.
parameters can then be referenced inside the controller actions, typically to perform a particular task
params method is the object which represents the parameters (or fields) coming in from the form.
Active Record is smart enough to automatically map column names to
model attributes,
Rails uses rake commands to run migrations,
and it's possible to undo a migration after it's been applied to your database
every Rails model can be initialized with its
respective attributes, which are automatically mapped to the respective
database columns.
migration creates a method named change which will be called when you
run this migration.
The action defined in this method is also reversible, which
means Rails knows how to reverse the change made by this migration, in case you
want to reverse it later
Migration filenames include a timestamp to ensure that they're processed in the
order that they were created.
@post.save returns a boolean indicating
whether the model was saved or not.
prevents an attacker from
setting the model's attributes by manipulating the hash passed to the model.
If you want to link to an action in the same controller, you don't
need to specify the :controller option, as Rails will use the current
controller by default.
inherits from
ActiveRecord::Base
Active Record supplies a great deal of functionality to
your Rails models for free, including 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.
Rails includes methods to help you validate the data that you send to models
Rails can validate a variety of conditions in a model,
including the presence or uniqueness of columns, their format, and the
existence of associated objects.
redirect_to will tell the browser to issue another request.
rendering is done within the same request as the form submission
Each request for a
comment has to keep track of the post to which the comment is attached, thus the
initial call to the find method of the Post model to get the post in question.
pluralize is a rails helper that takes a number and a string as its
arguments. If the number is greater than one, the string will be automatically pluralized.
The render method is used so that the @post object is passed back to the new template when it is rendered.
The method: :patch option tells Rails that we want this form to be submitted
via the PATCH HTTP method which is the HTTP method you're expected to use to
update resources according to the REST protocol.
it accepts a hash containing the attributes
that you want to update.
field_with_errors. You can define a css rule to make them
standout
belongs_to :post, which sets up an Active Record association
creates comments as a nested resource within posts
call destroy on Active Record objects when you want to delete
them from the database.
Rails allows you to
use the dependent option of an association to achieve this.
store all external data as UTF-8
you're better off
ensuring that all external data is UTF-8
use UTF-8 as the internal storage of your database
Rails defaults to converting data from your database into UTF-8 at
the boundary.
:patch
By default forms built with the form_for helper are sent via POST
The :method and :'data-confirm'
options are used as HTML5 attributes so that when the link is clicked,
Rails will first show a confirm dialog to the user, and then submit the link with method delete.
This is done via the JavaScript file jquery_ujs which is automatically included
into your application's layout (app/views/layouts/application.html.erb) when you
generated the application.
Without this file, the confirmation dialog box wouldn't appear.
just defines the partial template we want to render
As the render
method iterates over the @post.comments collection, it assigns each
comment to
a local variable named the same as the partial
use the authentication system
require and permit
the method is often made private to make sure
it can't be called outside its intended context.
standard CRUD actions in each
controller in the following order: index, show, new, edit, create, update
and destroy.
must be placed
before any private or protected method in the controller in order to work
{{ ... }} for Expressions to print to the template output
use a dot (.) to access attributes of a variable
the outer double-curly braces are not part of the
variable, but the print statement.
If you access variables inside tags don’t
put the braces around them.
If a variable or attribute does not exist, you will get back an undefined
value.
the default behavior is to evaluate to an empty string if
printed or iterated over, and to fail for every other operation.
if an object has an item and attribute with the same
name. Additionally, the attr() filter only looks up attributes.
Variables can be modified by filters. Filters are separated from the
variable by a pipe symbol (|) and may have optional arguments in
parentheses.
Multiple filters can be chained
Tests can be used
to test a variable against a common expression.
add is plus the name of the test after the variable.
to find out if a variable is defined, you can do name is defined,
which will then return true or false depending on whether name is defined
in the current template context.
strip whitespace in templates by hand. If you add a minus
sign (-) to the start or end of a block (e.g. a For tag), a
comment, or a variable expression, the whitespaces before or after
that block will be removed
not add whitespace between the tag and the minus sign
mark a block raw
Template inheritance
allows you to build a base “skeleton” template that contains all the common
elements of your site and defines blocks that child templates can override.
The {% extends %} tag is the key here. It tells the template engine that
this template “extends” another template.
access templates in subdirectories with a slash
can’t define multiple {% block %} tags with the same name in the
same template
use the special
self variable and call the block with that name
self.title()
super()
put the name of the block after the end tag for better
readability
if the block is replaced by
a child template, a variable would appear that was not defined in the block or
passed to the context.
setting the block to “scoped” by adding the scoped
modifier to a block declaration
If you have a variable that may
include any of the following chars (>, <, &, or ") you
SHOULD escape it unless the variable contains well-formed and trusted
HTML.
Jinja2 functions (macros, super, self.BLOCKNAME) always return template
data that is marked as safe.
With the default syntax, control structures appear inside
{% ... %} blocks.
the dictsort filter
loop.cycle
Unlike in Python, it’s not possible to break or continue in a loop
use loops recursively
add the recursive modifier
to the loop definition and call the loop variable with the new iterable
where you want to recurse.
The loop variable always refers to the closest (innermost) loop.
whether the value changed at all,
use it to test if a variable is defined, not
empty and not false
Macros are comparable with functions in regular programming languages.
If a macro name starts with an underscore, it’s not exported and can’t
be imported.
pass a macro to another macro
caller()
a single trailing newline is stripped if present
other whitespace (spaces, tabs, newlines etc.) is returned unchanged
a block tag works in “both”
directions. That is, a block tag doesn’t just provide a placeholder to fill
- it also defines the content that fills the placeholder in the parent.
Python dicts are not ordered
caller(user)
call(user)
This is a simple dialog rendered by using a macro and
a call block.
Filter sections allow you to apply regular Jinja2 filters on a block of
template data.
Assignments at
top level (outside of blocks, macros or loops) are exported from the template
like top level macros and can be imported by other templates.
using namespace
objects which allow propagating of changes across scopes
use block assignments to
capture the contents of a block into a variable name.
The extends tag can be used to extend one template from another.
Blocks are used for inheritance and act as both placeholders and replacements
at the same time.
The include statement is useful to include a template and return the
rendered contents of that file into the current namespace
Included templates have access to the variables of the active context by
default.
putting often used code into macros
imports are cached
and imported templates don’t have access to the current template variables,
just the globals by default.
Macros and variables starting with one or more underscores are private and
cannot be imported.
By default, included templates are passed the current context and imported
templates are not.
imports are often used just as a module that holds macros.
Integers and floating point numbers are created by just writing the
number down
Everything between two brackets is a list.
Tuples are like lists that cannot be modified (“immutable”).
A dict in Python is a structure that combines keys and values.
//
Divide two numbers and return the truncated integer result
The special constants true, false, and none are indeed lowercase
all Jinja identifiers are lowercase
(expr)
group an expression.
The is and in operators support negation using an infix notation
in
Perform a sequence / mapping containment test.
|
Applies a filter.
~
Converts all operands into strings and concatenates them.
use inline if expressions.
always an attribute is returned and items are not
looked up.
default(value, default_value=u'', boolean=False)¶
If the value is undefined it will return the passed default value,
otherwise the value of the variable
dictsort(value, case_sensitive=False, by='key', reverse=False)¶
Sort a dict and yield (key, value) pairs.
format(value, *args, **kwargs)¶
Apply python string formatting on an object
groupby(value, attribute)¶
Group a sequence of objects by a common attribute.
grouping by is stored in the grouper
attribute and the list contains all the objects that have this grouper
in common.
indent(s, width=4, first=False, blank=False, indentfirst=None)¶
Return a copy of the string with each line indented by 4 spaces. The
first line and blank lines are not indented by default.
join(value, d=u'', attribute=None)¶
Return a string which is the concatenation of the strings in the
sequence.
map()¶
Applies a filter on a sequence of objects or looks up an attribute.
pprint(value, verbose=False)¶
Pretty print a variable. Useful for debugging.
reject()¶
Filters a sequence of objects by applying a test to each object,
and rejecting the objects with the test succeeding.
replace(s, old, new, count=None)¶
Return a copy of the value with all occurrences of a substring
replaced with a new one.
round(value, precision=0, method='common')¶
Round the number to a given precision
even if rounded to 0 precision, a float is returned.
select()¶
Filters a sequence of objects by applying a test to each object,
and only selecting the objects with the test succeeding.
sort(value, reverse=False, case_sensitive=False, attribute=None)¶
Sort an iterable. Per default it sorts ascending, if you pass it
true as first argument it will reverse the sorting.
striptags(value)¶
Strip SGML/XML tags and replace adjacent whitespace by one space.
tojson(value, indent=None)¶
Dumps a structure to JSON so that it’s safe to use in <script>
tags.
trim(value)¶
Strip leading and trailing whitespace.
unique(value, case_sensitive=False, attribute=None)¶
Returns a list of unique items from the the given iterable
urlize(value, trim_url_limit=None, nofollow=False, target=None, rel=None)¶
Converts URLs in plain text into clickable links.
defined(value)¶
Return true if the variable is defined
in(value, seq)¶
Check if value is in seq.
mapping(value)¶
Return true if the object is a mapping (dict etc.).
number(value)¶
Return true if the variable is a number.
sameas(value, other)¶
Check if an object points to the same memory address than another
object
undefined(value)¶
Like defined() but the other way round.
A joiner is
passed a string and will return that string every time it’s called, except
the first time (in which case it returns an empty string).
namespace(...)¶
Creates a new container that allows attribute assignment using the
{% set %} tag
The with statement makes it possible to create a new inner scope.
Variables set within this scope are not visible outside of the scope.
activate and deactivate the autoescaping from within
the templates
With both trim_blocks and lstrip_blocks enabled, you can put block tags
on their own lines, and the entire block line will be removed when
rendered, preserving the whitespace of the contents
In most cases, the eligible DOM elements are identified by HTML5
data attributes.
using JavaScript to progressively
enhance the user experience for capable browsers without negatively impacting
clients that do not support or do not enable JavaScript.
jquery-ujs attaches a handler to links with the data-method attribute
When the link is clicked, the handler constructs an HTML form along with a hidden input that sets the _method parameter to the requested HTTP verb
jquery-ujs attaches a handler to links or forms with the data-confirm
attribute that displays a JavaScript confirmation dialog
Users double click links and buttons all the time.
Links and buttons that
have a data-disable-with attribute get a click handler that disables the
element and updates the text of the button to that which was provided in the
data attribute and disables the button.
If the action is performed via AJAX,
the handler will re-enable the button and reset the text when the request
completes.
Thanks to
jquery-ujs and Rails’ respond_with, setting remote: true is likely the
quickest way to get your Rails application making AJAX requests.
support both AJAX and standard
requests at the same time.
Cross-Site Request Forgery (CSRF) is an attack wherein the attacker tricks the
user into submitting a request to an application the user is likely already
authenticated to.