Action Controller Overview¶ ↑
In this guide you will learn how controllers work and how they fit into the request cycle in your application.
After reading this guide, you will know:
-
How to follow the flow of a request through a controller.
-
How to restrict parameters passed to your controller.
-
Why and how to store data in the session or cookies.
-
How to work with filters to execute code during request processing.
-
How to use Action Controller's built-in HTTP authentication.
-
How to stream data directly to the user's browser.
-
How to filter sensitive parameters so they do not appear in the application's log.
-
How to deal with exceptions that may be raised during request processing.
What Does a Controller Do?¶ ↑
Action Controller is the C in MVC. After routing has determined which controller to use for a request, your controller is responsible for making sense of the request and producing the appropriate output. Luckily, Action Controller does most of the groundwork for you and uses smart conventions to make this as straightforward as possible.
For most conventional RESTful applications, the controller will receive the request (this is invisible to you as the developer), fetch or save data from a model and use a view to create HTML output. If your controller needs to do things a little differently, that's not a problem, this is just the most common way for a controller to work.
A controller can thus be thought of as a middle man between models and views. It makes the model data available to the view so it can display that data to the user, and it saves or updates data from the user to the model.
NOTE: For more details on the routing process, see Rails Routing from the Outside In.
Controller Naming Convention¶ ↑
The naming convention of controllers in Rails favors pluralization of the
last word in the controller's name, although it is not strictly
required (e.g. ApplicationController
). For example,
ClientsController
is preferable to
ClientController
, SiteAdminsController
is
preferable to SiteAdminController
or
SitesAdminsController
, and so on.
Following this convention will allow you to use the default route
generators (e.g. resources
, etc) without needing to qualify
each :path
or :controller
, and keeps URL and path
helpers' usage consistent throughout your application. See Layouts & Rendering Guide for more
details.
NOTE: The controller naming convention differs from the naming convention of models, which are expected to be named in singular form.
Methods and Actions¶ ↑
A controller is a Ruby class which inherits from
ApplicationController
and has methods just like any other
class. When your application receives a request, the routing will determine
which controller and action to run, then Rails creates an instance of that
controller and runs the method with the same name as the action.
class ClientsController < ApplicationController def new end end
As an example, if a user goes to /clients/new
in your
application to add a new client, Rails will create an instance of
ClientsController
and run the new
method. Note
that the empty method from the example above would work just fine because
Rails will by default render the new.html.erb
view unless the
action says otherwise. The new
method could make available to
the view a @client
instance variable by creating a new
Client
:
def new @client = Client.new end
The Layouts & Rendering Guide explains this in more detail.
ApplicationController
inherits from
ActionController::Base
, which defines a number of helpful
methods. This guide will cover some of these, but if you're curious to
see what's in there, you can see all of them in the API documentation
or in the source itself.
Only public methods are callable as actions. It is a best practice to lower the visibility of methods which are not intended to be actions, like auxiliary methods or filters.
Parameters¶ ↑
You will probably want to access data sent in by the user or other
parameters in your controller actions. There are two kinds of parameters
possible in a web application. The first are parameters that are sent as
part of the URL, called query string parameters. The query string is
everything after “?” in the URL. The second type of parameter is usually
referred to as POST data. This information usually 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. Rails does not make any
distinction between query string parameters and POST parameters, and both
are available in the params
hash in your controller:
class ClientsController < ApplicationController # This action uses query string parameters because it gets run # by an HTTP GET request, but this does not make any difference # to the way in which the parameters are accessed. The URL for # this action would look like this in order to list activated # clients: /clients?status=activated def index if params[:status] == "activated" @clients = Client.activated else @clients = Client.inactivated end end # This action uses POST parameters. They are most likely coming # from an HTML form which the user has submitted. The URL for # this RESTful request will be "/clients", and the data will be # sent as part of the request body. def create @client = Client.new(params[:client]) if @client.save redirect_to @client else # This line overrides the default rendering behavior, which # would have been to render the "create" view. render "new" end end end
Hash and Array Parameters¶ ↑
The params
hash is not limited to one-dimensional keys and
values. It can contain arrays and (nested) hashes. To send an array of
values, append an empty pair of square brackets “[]” to the key name:
GET /clients?ids[]=1&ids[]=2&ids[]=3
NOTE: The actual URL in this example will be encoded as “/clients?ids%5b%5d=1&ids%5b%5d=2&ids%5b%5d=3” as “[” and “]” are not allowed in URLs. Most of the time you don't have to worry about this because the browser will take care of it for you, and Rails will decode it back when it receives it, but if you ever find yourself having to send those requests to the server manually you have to keep this in mind.
The value of params[:ids]
will now be ["1",
"2", "3"]
. Note that parameter values are always
strings; Rails makes no attempt to guess or cast the type.
NOTE: Values such as []
, [nil]
or [nil,
nil, ...]
in params
are replaced with nil
for security reasons by default. See Security Guide for more
information.
To send a hash you include the key name inside the brackets:
<form accept-charset="UTF-8" action="/clients" method="post"> <input type="text" name="client[name]" value="Acme" /> <input type="text" name="client[phone]" value="12345" /> <input type="text" name="client[address][postcode]" value="12345" /> <input type="text" name="client[address][city]" value="Carrot City" /> </form>
When this form is submitted, the value of params[:client]
will
be { "name" => "Acme", "phone" =>
"12345", "address" => { "postcode" =>
"12345", "city" => "Carrot City" }
}
. Note the nested hash in params[:client][:address]
.
Note that the params
hash is actually an instance of
ActiveSupport::HashWithIndifferentAccess
, which acts like a
hash but lets you use symbols and strings interchangeably as keys.
JSON parameters¶ ↑
If you're writing a web service application, you might find yourself
more comfortable accepting parameters in JSON format. If the “Content-Type”
header of your request is set to “application/json”, Rails will
automatically convert your parameters into the params
hash,
which you can access as you would normally.
So for example, if you are sending this JSON content:
{ "company": { "name": "acme", "address": "123 Carrot Street" } }
You'll get params[:company]
as { "name"
=> "acme", "address" => "123 Carrot
Street" }
.
Also, if you've turned on config.wrap_parameters
in your
initializer or calling wrap_parameters
in your controller, you
can safely omit the root element in the JSON parameter. The parameters will
be cloned and wrapped in the key according to your controller's name by
default. So the above parameter can be written as:
{ "name": "acme", "address": "123 Carrot Street" }
And assume that you're sending the data to
CompaniesController
, it would then be wrapped in
:company
key like this:
{ name: "acme", address: "123 Carrot Street", company: { name: "acme", address: "123 Carrot Street" } }
You can customize the name of the key or specific parameters you want to wrap by consulting the API documentation
NOTE: Support for parsing XML parameters has been extracted into a gem
named actionpack-xml_parser
Routing Parameters¶ ↑
The params
hash will always contain the
:controller
and :action
keys, but you should use
the methods controller_name
and action_name
instead to access these values. Any other parameters defined by the
routing, such as :id
will also be available. As an example,
consider a listing of clients where the list can show either active or
inactive clients. We can add a route which captures the
:status
parameter in a “pretty” URL:
get '/clients/:status' => 'clients#index', foo: 'bar'
In this case, when a user opens the URL /clients/active
,
params[:status]
will be set to “active”. When this route is
used, params[:foo]
will also be set to “bar” just like it was
passed in the query string. In the same way params[:action]
will contain “index”.
default_url_options
¶ ↑
You can set global default parameters for URL generation by defining a
method called default_url_options
in your controller. Such a
method must return a hash with the desired defaults, whose keys must be
symbols:
class ApplicationController < ActionController::Base def default_url_options { locale: I18n.locale } end end
These options will be used as a starting point when generating URLs, so
it's possible they'll be overridden by the options passed in
url_for
calls.
If you define default_url_options
in
ApplicationController
, as in the example above, it would be
used for all URL generation. The method can also be defined in one specific
controller, in which case it only affects URLs generated there.
Strong Parameters¶ ↑
With strong parameters, Action Controller parameters are forbidden to be used in Active Model mass assignments until they have been whitelisted. This means you'll have to make a conscious choice about which attributes to allow for mass updating and thus prevent accidentally exposing that which shouldn't be exposed.
In addition, parameters can be marked as required and flow through a predefined raise/rescue flow to end up as a 400 Bad Request with no effort.
class PeopleController < ActionController::Base # This will raise an ActiveModel::ForbiddenAttributes exception # because it's using mass assignment without an explicit permit # step. def create Person.create(params[:person]) end # This will pass with flying colors as long as there's a person key # in the parameters, otherwise it'll raise a # ActionController::ParameterMissing exception, which will get # caught by ActionController::Base and turned into that 400 Bad # Request reply. def update person = current_account.people.find(params[:id]) person.update!(person_params) redirect_to person end private # Using a private method to encapsulate the permissible parameters # is just a good pattern since you'll be able to reuse the same # permit list between create and update. Also, you can specialize # this method with per-user checking of permissible attributes. def person_params params.require(:person).permit(:name, :age) end end
Permitted Scalar Values¶ ↑
Given
params.permit(:id)
the key :id
will pass the whitelisting if it appears in
params
and it has a permitted scalar value associated.
Otherwise the key is going to be filtered out, so arrays, hashes, or any
other objects cannot be injected.
The permitted scalar types are String
, Symbol
,
NilClass
, Numeric
, TrueClass
,
FalseClass
, Date
, Time
,
DateTime
, StringIO
, IO
,
ActionDispatch::Http::UploadedFile
and
Rack::Test::UploadedFile
.
To declare that the value in params
must be an array of
permitted scalar values map the key to an empty array:
params.permit(id: [])
To whitelist an entire hash of parameters, the permit!
method
can be used:
params.require(:log_entry).permit!
This will mark the :log_entry
parameters hash and any sub-hash
of it permitted. Extreme care should be taken when using
permit!
as it will allow all current and future model
attributes to be mass-assigned.
Nested Parameters¶ ↑
You can also use permit on nested parameters, like:
params.permit(:name, { emails: [] }, friends: [ :name, { family: [ :name ], hobbies: [] }])
This declaration whitelists the name
, emails
and
friends
attributes. It is expected that emails
will be an array of permitted scalar values and that friends
will be an array of resources with specific attributes : they should have a
name
attribute (any permitted scalar values allowed), a
hobbies
attribute as an array of permitted scalar values, and
a family
attribute which is restricted to having a
name
(any permitted scalar values allowed, too).
More Examples¶ ↑
You want to also use the permitted attributes in the new
action. This raises the problem that you can't use require
on the root key because normally it does not exist when calling
new
:
# using `fetch` you can supply a default and use # the Strong Parameters API from there. params.fetch(:blog, {}).permit(:title, :author)
accepts_nested_attributes_for
allows you to update and destroy
associated records. This is based on the id
and
_destroy
parameters:
# permit :id and :_destroy params.require(:author).permit(:name, books_attributes: [:title, :id, :_destroy])
Hashes with integer keys are treated differently and you can declare the
attributes as if they were direct children. You get these kinds of
parameters when you use accepts_nested_attributes_for
in
combination with a has_many
association:
# To whitelist the following data: # {"book" => {"title" => "Some Book", # "chapters_attributes" => { "1" => {"title" => "First Chapter"}, # "2" => {"title" => "Second Chapter"}}}} params.require(:book).permit(:title, chapters_attributes: [:title])
Outside the Scope of Strong Parameters¶ ↑
The strong parameter API was designed with the most common use cases in mind. It is not meant as a silver bullet to handle all your whitelisting problems. However you can easily mix the API with your own code to adapt to your situation.
Imagine a scenario where you have parameters representing a product name and a hash of arbitrary data associated with that product, and you want to whitelist the product name attribute but also the whole data hash. The strong parameters API doesn't let you directly whitelist the whole of a nested hash with any keys, but you can use the keys of your nested hash to declare what to whitelist:
def product_params params.require(:product).permit(:name, data: params[:product][:data].try(:keys)) end
Session¶ ↑
Your application has a session for each user in which you can store small amounts of data that will be persisted between requests. The session is only available in the controller and the view and can use one of a number of different storage mechanisms:
-
ActionDispatch::Session::CookieStore
- Stores everything on the client. -
ActionDispatch::Session::CacheStore
- Stores the data in the Rails cache. -
ActionDispatch::Session::ActiveRecordStore
- Stores the data in a database using Active Record. (requireactiverecord-session_store
gem). -
ActionDispatch::Session::MemCacheStore
- Stores the data in a memcached cluster (this is a legacy implementation; consider using CacheStore instead).
All session stores use a cookie to store a unique ID for each session (you must use a cookie, Rails will not allow you to pass the session ID in the URL as this is less secure).
For most stores, this ID is used to look up the session data on the server, e.g. in a database table. There is one exception, and that is the default and recommended session store - the CookieStore - which stores all session data in the cookie itself (the ID is still available to you if you need it). This has the advantage of being very lightweight and it requires zero setup in a new application in order to use the session. The cookie data is cryptographically signed to make it tamper-proof. And it is also encrypted so anyone with access to it can't read its contents. (Rails will not accept it if it has been edited).
The CookieStore can store around 4kB of data - much less than the others - but this is usually enough. Storing large amounts of data in the session is discouraged no matter which session store your application uses. You should especially avoid storing complex objects (anything other than basic Ruby objects, the most common example being model instances) in the session, as the server might not be able to reassemble them between requests, which will result in an error.
If your user sessions don't store critical data or don't need to be
around for long periods (for instance if you just use the flash for
messaging), you can consider using
ActionDispatch::Session::CacheStore
. This will store sessions
using the cache implementation you have configured for your application.
The advantage of this is that you can use your existing cache
infrastructure for storing sessions without requiring any additional setup
or administration. The downside, of course, is that the sessions will be
ephemeral and could disappear at any time.
Read more about session storage in the Security Guide.
If you need a different session storage mechanism, you can change it in the
config/initializers/session_store.rb
file:
# Use the database for sessions instead of the cookie-based default, # which shouldn't be used to store highly confidential information # (create the session table with "rails g active_record:session_migration") # Rails.application.config.session_store :active_record_store
Rails sets up a session key (the name of the cookie) when signing the
session data. These can also be changed in
config/initializers/session_store.rb
:
# Be sure to restart your server when you modify this file. Rails.application.config.session_store :cookie_store, key: '_your_app_session'
You can also pass a :domain
key and specify the domain name
for the cookie:
# Be sure to restart your server when you modify this file. Rails.application.config.session_store :cookie_store, key: '_your_app_session', domain: ".example.com"
Rails sets up (for the CookieStore) a secret key used for signing the
session data. This can be changed in config/secrets.yml
# Be sure to restart your server when you modify this file. # Your secret key is used for verifying the integrity of signed cookies. # If you change this key, all old signed cookies will become invalid! # Make sure the secret is at least 30 characters and all random, # no regular words or you'll be exposed to dictionary attacks. # You can use `rake secret` to generate a secure secret key. # Make sure the secrets in this file are kept private # if you're sharing your code publicly. development: secret_key_base: a75d... test: secret_key_base: 492f... # Do not keep production secrets in the repository, # instead read values from the environment. production: secret_key_base: <%Q= ENV["SECRET_KEY_BASE"] %>
NOTE: Changing the secret when using the CookieStore
will
invalidate all existing sessions.
Accessing the Session¶ ↑
In your controller you can access the session through the
session
instance method.
NOTE: Sessions are lazily loaded. If you don't access sessions in your action's code, they will not be loaded. Hence you will never need to disable sessions, just not accessing them will do the job.
Session values are stored using key/value pairs like a hash:
class ApplicationController < ActionController::Base private # Finds the User with the ID stored in the session with the key # :current_user_id This is a common way to handle user login in # a Rails application; logging in sets the session value and # logging out removes it. def current_user @_current_user ||= session[:current_user_id] && User.find_by(id: session[:current_user_id]) end end
To store something in the session, just assign it to the key like a hash:
class LoginsController < ApplicationController # "Create" a login, aka "log the user in" def create if user = User.authenticate(params[:username], params[:password]) # Save the user ID in the session so it can be used in # subsequent requests session[:current_user_id] = user.id redirect_to root_url end end end
To remove something from the session, assign that key to be
nil
:
class LoginsController < ApplicationController # "Delete" a login, aka "log the user out" def destroy # Remove the user id from the session @_current_user = session[:current_user_id] = nil redirect_to root_url end end
To reset the entire session, use reset_session
.
The Flash¶ ↑
The flash is a special part of the session which is cleared with each request. This means that values stored there will only be available in the next request, which is useful for passing error messages etc.
It is accessed in much the same way as the session, as a hash (it's a FlashHash instance).
Let's use the act of logging out as an example. The controller can send a message which will be displayed to the user on the next request:
class LoginsController < ApplicationController def destroy session[:current_user_id] = nil flash[:notice] = "You have successfully logged out." redirect_to root_url end end
Note that it is also possible to assign a flash message as part of the
redirection. You can assign :notice
, :alert
or
the general purpose :flash
:
redirect_to root_url, notice: "You have successfully logged out." redirect_to root_url, alert: "You're stuck here!" redirect_to root_url, flash: { referral_code: 1234 }
The destroy
action redirects to the application's
root_url
, where the message will be displayed. Note that
it's entirely up to the next action to decide what, if anything, it
will do with what the previous action put in the flash. It's
conventional to display any error alerts or notices from the flash in the
application's layout:
<html> <!-- <head/> --> <body> <% flash.each do |name, msg| -%> <%= content_tag :div, msg, class: name %> <% end -%> <!-- more content --> </body> </html>
This way, if an action sets a notice or an alert message, the layout will display it automatically.
You can pass anything that the session can store; you're not limited to notices and alerts:
<% if flash[:just_signed_up] %> <p class="welcome">Welcome to our site!</p> <% end %>
If you want a flash value to be carried over to another request, use the
keep
method:
class MainController < ApplicationController # 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 # You can also use a key to keep only some kind of value. # flash.keep(:notice) redirect_to users_url end end
flash.now
¶ ↑
By default, adding values to the flash will make them available to the next
request, but sometimes you may want to access those values in the same
request. For example, 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, but you may still want to display a
message using the flash. To do this, you can use flash.now
in
the same way you use the normal flash
:
class ClientsController < ApplicationController def create @client = Client.new(params[:client]) if @client.save # ... else flash.now[:error] = "Could not save client" render action: "new" end end end
Cookies¶ ↑
Your application can store small amounts of data on the client - called
cookies - that will be persisted across requests and even sessions. Rails
provides easy access to cookies via the cookies
method, which
- much like the session
- works like a hash:
class CommentsController < ApplicationController def new # Auto-fill the commenter's name if it has been stored in a cookie @comment = Comment.new(author: cookies[:commenter_name]) end def create @comment = Comment.new(params[:comment]) if @comment.save flash[:notice] = "Thanks for your comment!" if params[:remember_name] # Remember the commenter's name. cookies[:commenter_name] = @comment.author else # Delete cookie for the commenter's name cookie, if any. cookies.delete(:commenter_name) end redirect_to @comment.article else render action: "new" end end end
Note that while for session values you set the key to nil
, to
delete a cookie value you should use cookies.delete(:key)
.
Rails also provides a signed cookie jar and an encrypted cookie jar for storing sensitive data. The signed cookie jar appends a cryptographic signature on the cookie values to protect their integrity. The encrypted cookie jar encrypts the values in addition to signing them, so that they cannot be read by the end user. Refer to the API documentation for more details.
These special cookie jars use a serializer to serialize the assigned values into strings and deserializes them into Ruby objects on read.
You can specify what serializer to use:
Rails.application.config.action_dispatch.cookies_serializer = :json
The default serializer for new applications is :json
. For
compatibility with old applications with existing cookies,
:marshal
is used when serializer
option is not
specified.
You may also set this option to :hybrid
, in which case Rails
would transparently deserialize existing (Marshal
-serialized)
cookies on read and re-write them in the JSON
format. This is
useful for migrating existing applications to the :json
serializer.
It is also possible to pass a custom serializer that responds to
load
and dump
:
Rails.application.config.action_dispatch.cookies_serializer = MyCustomSerializer
When using the :json
or :hybrid
serializer, you
should beware that not all Ruby objects can be serialized as JSON. For
example, Date
and Time
objects will be serialized
as strings, and Hash
es will have their keys stringified.
class CookiesController < ApplicationController def set_cookie cookies.encrypted[:expiration_date] = Date.tomorrow # => Thu, 20 Mar 2014 redirect_to action: 'read_cookie' end def read_cookie cookies.encrypted[:expiration_date] # => "2014-03-20" end end
It's advisable that you only store simple data (strings and numbers) in cookies. If you have to store complex objects, you would need to handle the conversion manually when reading the values on subsequent requests.
If you use the cookie session store, this would apply to the
session
and flash
hash as well.
Rendering XML and JSON data¶ ↑
ActionController makes it extremely easy to render XML
or
JSON
data. If you've generated a controller using
scaffolding, it would look something like this:
class UsersController < ApplicationController def index @users = User.all respond_to do |format| format.html # index.html.erb format.xml { render xml: @users} format.json { render json: @users} end end end
You may notice in the above code that we're using render xml:
@users
, not render xml: @users.to_xml
. If the object is
not a String, then Rails will automatically invoke to_xml
for
us.
Filters¶ ↑
Filters are methods that are run before, after or “around” a controller action.
Filters are inherited, so if you set a filter on
ApplicationController
, it will be run on every controller in
your application.
“Before” filters may halt the request cycle. A common “before” filter is one which requires that a user is logged in for an action to be run. You can define the filter method this way:
class ApplicationController < ActionController::Base before_action :require_login private def require_login unless logged_in? flash[:error] = "You must be logged in to access this section" redirect_to new_login_url # halts request cycle end end end
The method simply stores an error message in the flash and redirects to the login form if the user is not logged in. If a “before” filter renders or redirects, the action will not run. If there are additional filters scheduled to run after that filter, they are also cancelled.
In this example the filter is added to ApplicationController
and thus all controllers in the application inherit it. This will make
everything in the application require the user to be logged in in order to
use it. For obvious reasons (the user wouldn't be able to log in in the
first place!), not all controllers or actions should require this. You can
prevent this filter from running before particular actions with
skip_before_action
:
class LoginsController < ApplicationController skip_before_action :require_login, only: [:new, :create] end
Now, the LoginsController
's new
and
create
actions will work as before without requiring the user
to be logged in. The :only
option is used to only skip this
filter for these actions, and there is also an :except
option
which works the other way. These options can be used when adding filters
too, so you can add a filter which only runs for selected actions in the
first place.
After Filters and Around Filters¶ ↑
In addition to “before” filters, you can also run filters after an action has been executed, or both before and after.
“After” filters are similar to “before” filters, but because the action has already been run they have access to the response data that's about to be sent to the client. Obviously, “after” filters cannot stop the action from running.
“Around” filters are responsible for running their associated actions by yielding, similar to how Rack middlewares work.
For example, in a website where changes have an approval workflow an administrator could be able to preview them easily, just apply them within a transaction:
class ChangesController < ApplicationController around_action :wrap_in_transaction, only: :show private def wrap_in_transaction ActiveRecord::Base.transaction do begin yield ensure raise ActiveRecord::Rollback end end end end
Note that an “around” filter also wraps rendering. In particular, if in the example above, the view itself reads from the database (e.g. via a scope), it will do so within the transaction and thus present the data to preview.
You can choose not to yield and build the response yourself, in which case the action will not be run.
Other Ways to Use Filters¶ ↑
While the most common way to use filters is by creating private methods and using *_action to add them, there are two other ways to do the same thing.
The first is to use a block directly with the *_action methods. The block
receives the controller as an argument, and the require_login
filter from above could be rewritten to use a block:
class ApplicationController < ActionController::Base before_action do |controller| unless controller.send(:logged_in?) flash[:error] = "You must be logged in to access this section" redirect_to new_login_url end end end
Note that the filter in this case uses send
because the
logged_in?
method is private and the filter is not run in the
scope of the controller. This is not the recommended way to implement this
particular filter, but in more simple cases it might be useful.
The second way is to use a class (actually, any object that responds to the right methods will do) to handle the filtering. This is useful in cases that are more complex and cannot be implemented in a readable and reusable way using the two other methods. As an example, you could rewrite the login filter again to use a class:
class ApplicationController < ActionController::Base before_action LoginFilter end class LoginFilter def self.before(controller) unless controller.send(:logged_in?) controller.flash[:error] = "You must be logged in to access this section" controller.redirect_to controller.new_login_url end end end
Again, this is not an ideal example for this filter, because it's not
run in the scope of the controller but gets the controller passed as an
argument. The filter class must implement a method with the same name as
the filter, so for the before_action
filter the class must
implement a before
method, and so on. The around
method must yield
to execute the action.
Request Forgery Protection¶ ↑
Cross-site request forgery is a type of attack in which a site tricks a user into making requests on another site, possibly adding, modifying or deleting data on that site without the user's knowledge or permission.
The first step to avoid this is to 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. However, a malicious site can still send a non-GET request to your site quite easily, and that's where the request forgery protection comes in. As the name says, it protects from forged requests.
The way this is done is to 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.
If you generate a form like this:
<%= form_for @user do |f| %> <%= f.text_field :username %> <%= f.text_field :password %> <% end %>
You will see how the token gets added as a hidden field:
<form accept-charset="UTF-8" action="/users/1" method="post"> <input type="hidden" value="67250ab105eb5ad10851c00a5621854a23af5489" name="authenticity_token"/> <!-- fields --> </form>
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. If you're writing a form manually or
need to add the token for another reason, it's available through the
method form_authenticity_token
:
The form_authenticity_token
generates a valid authentication
token. That's useful in places where Rails does not add it
automatically, like in custom Ajax calls.
The Security Guide has more about this and a lot of other security-related issues that you should be aware of when developing a web application.
The Request and Response Objects¶ ↑
In every controller there are two accessor methods pointing to the request
and the response objects associated with the request cycle that is
currently in execution. The request
method contains an
instance of AbstractRequest
and the response
method returns a response object representing what is going to be sent back
to the client.
The request
Object¶ ↑
The request object contains a lot of useful information about the request coming in from the client. To get a full list of the available methods, refer to the API documentation. Among the properties that you can access on this object are:
| Property of request
| Purpose | | —————————————– |
——————————————————————————– | | host | The hostname used for this request.
| | domain(n=2) | The hostname's first n
segments,
starting from the right (the TLD). | | format | The content type requested
by the client. | | method | The HTTP method used for the request. | | get?,
post?, patch?, put?, delete?, head? | Returns true if the HTTP method is
GET/POST/PATCH/PUT/DELETE/HEAD. | | headers | Returns a hash containing the
headers associated with the request. | | port | The port number (integer)
used for the request. | | protocol | Returns a string containing the
protocol used plus “://”, for example “http://”. | | query_string | The
query string part of the URL, i.e., everything after “?”. | | remote_ip |
The IP address of the client. | | url | The entire URL used for the
request. |
path_parameters
, query_parameters
, and request_parameters
¶ ↑
Rails collects all of the parameters sent along with the request in the
params
hash, whether they are sent as part of the query string
or the post body. The request object has three accessors that give you
access to these parameters depending on where they came from. The
query_parameters
hash contains parameters that were sent as
part of the query string while the request_parameters
hash
contains parameters sent as part of the post body. The
path_parameters
hash contains parameters that were recognized
by the routing as being part of the path leading to this particular
controller and action.
The response
Object¶ ↑
The response object is not usually used directly, but is built up during the execution of the action and rendering of the data that is being sent back to the user, but sometimes - like in an after filter - it can be useful to access the response directly. Some of these accessor methods also have setters, allowing you to change their values.
| Property of response
| Purpose | | ———————- |
————————————————————————————————— | | body | This is the string of data
being sent back to the client. This is most often HTML. | | status | The
HTTP status code for the response, like 200 for a successful request or 404
for file not found. | | location | The URL the client is being redirected
to, if any. | | content_type | The content type of the response. | |
charset | The character set being used for the response. Default is
“utf-8”. | | headers | Headers used for the response. |
Setting Custom Headers¶ ↑
If you want to set custom headers for a response then
response.headers
is the place to do it. The headers attribute
is a hash which maps header names to their values, and Rails will set some
of them automatically. If you want to add or change a header, just assign
it to response.headers
this way:
response.headers["Content-Type"] = "application/pdf"
Note: in the above case it would make more sense to use the
content_type
setter directly.
HTTP Authentications¶ ↑
Rails comes with two built-in HTTP authentication mechanisms:
-
Basic Authentication
-
Digest Authentication
HTTP Basic Authentication¶ ↑
HTTP basic authentication is an authentication scheme that is supported by
the majority of browsers and other HTTP clients. As an example, consider an
administration section which will only be available by entering a username
and a password into the browser's HTTP basic dialog window. Using the
built-in authentication is quite easy and only requires you to use one
method, http_basic_authenticate_with
.
class AdminsController < ApplicationController http_basic_authenticate_with name: "humbaba", password: "5baa61e4" end
With this in place, you can create namespaced controllers that inherit from
AdminsController
. The filter will thus be run for all actions
in those controllers, protecting them with HTTP basic authentication.
HTTP Digest Authentication¶ ↑
HTTP digest authentication is superior to the basic authentication as it
does not require the client to send an unencrypted password over the
network (though HTTP basic authentication is safe over HTTPS). Using digest
authentication with Rails is quite easy and only requires using one method,
authenticate_or_request_with_http_digest
.
class AdminsController < ApplicationController USERS = { "lifo" => "world" } before_action :authenticate private def authenticate authenticate_or_request_with_http_digest do |username| USERS[username] end end end
As seen in the example above, the
authenticate_or_request_with_http_digest
block takes only one
argument - the username. And the block returns the password. Returning
false
or nil
from the
authenticate_or_request_with_http_digest
will cause
authentication failure.
Streaming and File Downloads¶ ↑
Sometimes you may want to send a file to the user instead of rendering an
HTML page. All controllers in Rails have the send_data
and the
send_file
methods, which will both stream data to the client.
send_file
is a convenience method that lets you provide the
name of a file on the disk and it will stream the contents of that file for
you.
To stream data to the client, use send_data
:
require "prawn" class ClientsController < ApplicationController # Generates a PDF document with information on the client and # returns it. The user will get the PDF as a file download. def download_pdf client = Client.find(params[:id]) send_data generate_pdf(client), filename: "#{client.name}.pdf", type: "application/pdf" end private def generate_pdf(client) Prawn::Document.new do text client.name, align: :center text "Address: #{client.address}" text "Email: #{client.email}" end.render end end
The download_pdf
action in the example above will call a
private method which actually generates the PDF document and returns it as
a string. This string will then be streamed to the client as a file
download and a filename will be suggested to the user. Sometimes when
streaming files to the user, you may not want them to download the file.
Take images, for example, which can be embedded into HTML pages. To tell
the browser a file is not meant to be downloaded, you can set the
:disposition
option to “inline”. The opposite and default
value for this option is “attachment”.
Sending Files¶ ↑
If you want to send a file that already exists on disk, use the
send_file
method.
class ClientsController < ApplicationController # Stream a file that has already been generated and stored on disk. def download_pdf client = Client.find(params[:id]) send_file("#{Rails.root}/files/clients/#{client.id}.pdf", filename: "#{client.name}.pdf", type: "application/pdf") end end
This will read and stream the file 4kB at the time, avoiding loading the
entire file into memory at once. You can turn off streaming with the
:stream
option or adjust the block size with the
:buffer_size
option.
If :type
is not specified, it will be guessed from the file
extension specified in :filename
. If the content type is not
registered for the extension, application/octet-stream
will be
used.
WARNING: Be careful when using data coming from the client (params, cookies, etc.) to locate the file on disk, as this is a security risk that might allow someone to gain access to files they are not meant to.
TIP: It is not recommended that you stream static files through Rails if 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.
RESTful Downloads¶ ↑
While send_data
works just fine, if you are creating a RESTful
application 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. Rails
provides an easy and quite sleek way of doing “RESTful downloads”.
Here's how you can rewrite the example so that the PDF download is a
part of the show
action, without any streaming:
class ClientsController < ApplicationController # The user can request to receive this resource as HTML or PDF. def show @client = Client.find(params[:id]) respond_to do |format| format.html format.pdf { render pdf: generate_pdf(@client) } end end end
In order for this example to work, you have to add the PDF MIME type to
Rails. This can be done by adding the following line to the file
config/initializers/mime_types.rb
:
Mime::Type.register "application/pdf", :pdf
NOTE: Configuration files are not reloaded on each request, so you have to restart the server in order for their changes to take effect.
Now the user can request to get a PDF version of a client just by adding “.pdf” to the URL:
GET /clients/1.pdf
Live Streaming of Arbitrary Data¶ ↑
Rails allows you to stream more than just files. In fact, you can stream
anything you would like in a response object. The
ActionController::Live
module allows you to create a
persistent connection with a browser. Using this module, you will be able
to send arbitrary data to the browser at specific points in time.
Incorporating Live Streaming¶ ↑
Including ActionController::Live
inside of your controller
class will provide all actions inside of the controller the ability to
stream data. You can mix in the module like so:
class MyController < ActionController::Base include ActionController::Live def stream response.headers['Content-Type'] = 'text/event-stream' 100.times { response.stream.write "hello world\n" sleep 1 } ensure response.stream.close end end
The above code will keep a persistent connection with the browser and send
100 messages of "hello world\n"
, each one second
apart.
There are a couple of things to notice in the above example. We need to
make sure to close the response stream. Forgetting to close the stream will
leave the socket open forever. We also have to set the content type to
text/event-stream
before we write to the response stream. This
is because headers cannot be written after the response has been committed
(when response.committed
returns a truthy value), which occurs
when you write
or commit
the response stream.
Example Usage¶ ↑
Let's suppose that you were making a Karaoke machine and a user wants
to get the lyrics for a particular song. Each Song
has a
particular number of lines and each line takes time num_beats
to finish singing.
If we wanted to return the lyrics in Karaoke fashion (only sending the line
when the singer has finished the previous line), then we could use
ActionController::Live
as follows:
class LyricsController < ActionController::Base include ActionController::Live def show response.headers['Content-Type'] = 'text/event-stream' song = Song.find(params[:id]) song.each do |line| response.stream.write line.lyrics sleep line.num_beats end ensure response.stream.close end end
The above code sends the next line only after the singer has completed the previous line.
Streaming Considerations¶ ↑
Streaming arbitrary data is an extremely powerful tool. As shown in the previous examples, you can choose when and what to send across a response stream. However, you should also note the following things:
-
Each response stream creates a new thread and copies over the thread local variables from the original thread. Having too many thread local variables can negatively impact performance. Similarly, a large number of threads can also hinder performance.
-
Failing to close the response stream will leave the corresponding socket open forever. Make sure to call
close
whenever you are using a response stream. -
WEBrick servers buffer all responses, and so including
ActionController::Live
will not work. You must use a web server which does not automatically buffer responses.
Log Filtering¶ ↑
Rails keeps a log file for each environment in the log
folder.
These are extremely useful when debugging what's actually going on in
your application, but in a live application you may not want every bit of
information to be stored in the log file.
Parameters Filtering¶ ↑
You can filter out sensitive request parameters from your log files by
appending them to config.filter_parameters
in the application
configuration. These parameters will be marked [FILTERED] in the log.
config.filter_parameters << :password
Redirects Filtering¶ ↑
Sometimes it's desirable to filter out from log files some sensitive
locations your application is redirecting to. You can do that by using the
config.filter_redirect
configuration option:
config.filter_redirect << 's3.amazonaws.com'
You can set it to a String, a Regexp, or an array of both.
config.filter_redirect.concat ['s3.amazonaws.com', /private_path/]
Matching URLs will be marked as '[FILTERED]'.
Rescue¶ ↑
Most likely your application is going to contain bugs or otherwise throw an
exception that needs to be handled. For example, if the user follows a link
to a resource that no longer exists in the database, Active Record will
throw the ActiveRecord::RecordNotFound
exception.
Rails' default exception handling displays a “500 Server Error” message for all exceptions. If the request was made locally, a nice traceback and some added information gets displayed so you can figure out what went wrong and deal with it. If the request was remote Rails will just display a simple “500 Server Error” message to the user, or a “404 Not Found” if there was a routing error or a record could not be found. Sometimes you might want to customize how these errors are caught and how they're displayed to the user. There are several levels of exception handling available in a Rails application:
The Default 500 and 404 Templates¶ ↑
By default a production application will render either a 404 or a 500 error
message. These messages are contained in static HTML files in the
public
folder, in 404.html
and
500.html
respectively. You can customize these files to add
some extra information and layout, but remember that they are static; i.e.
you can't use RHTML or layouts in them, just plain HTML.
rescue_from
¶ ↑
If you want to do something a bit more elaborate when catching errors, you
can use rescue_from
, which handles exceptions of a certain
type (or multiple types) in an entire controller and its subclasses.
When an exception occurs which is caught by a rescue_from
directive, the exception object is passed to the handler. The handler can
be a method or a Proc
object passed to the :with
option. You can also use a block directly instead of an explicit
Proc
object.
Here's how you can use rescue_from
to intercept all
ActiveRecord::RecordNotFound
errors and do something with
them.
class ApplicationController < ActionController::Base rescue_from ActiveRecord::RecordNotFound, with: :record_not_found private def record_not_found render plain: "404 Not Found", status: 404 end end
Of course, this example is anything but elaborate and doesn't improve on the default exception handling at all, but once you can catch all those exceptions you're free to do whatever you want with them. For example, you could create custom exception classes that will be thrown when a user doesn't have access to a certain section of your application:
class ApplicationController < ActionController::Base rescue_from User::NotAuthorized, with: :user_not_authorized private def user_not_authorized flash[:error] = "You don't have access to this section." redirect_to :back end end class ClientsController < ApplicationController # Check that the user has the right authorization to access clients. before_action :check_authorization # Note how the actions don't have to worry about all the auth stuff. def edit @client = Client.find(params[:id]) end private # If the user is not authorized, just throw the exception. def check_authorization raise User::NotAuthorized unless current_user.admin? end end
WARNING: You shouldn't do rescue_from Exception
or
rescue_from StandardError
unless you have a particular reason
as it will cause serious side-effects (e.g. you won't be able to see
exception details and tracebacks during development).
NOTE: Certain exceptions are only rescuable from the
ApplicationController
class, as they are raised before the
controller gets initialized and the action gets executed. See Pratik
Naik's article on
the subject for more information.
Force HTTPS protocol¶ ↑
Sometime you might want to force a particular controller to only be
accessible via an HTTPS protocol for security reasons. You can use the
force_ssl
method in your controller to enforce that:
class DinnerController force_ssl end
Just like the filter, you could also pass :only
and
:except
to enforce the secure connection only to specific
actions:
class DinnerController force_ssl only: :cheeseburger # or force_ssl except: :cheeseburger end
Please note that if you find yourself adding force_ssl
to many
controllers, you may want to force the whole application to use HTTPS
instead. In that case, you can set the config.force_ssl
in
your environment file.


Methods
CalculateSinglePhasePower(voltage, current) → {Promise}
Calcualte single phase power based on measured voltage and current
Parameters:
| Name | Type | Description |
|---|---|---|
voltage |
number | Measured voltage in Volts |
current |
number | Measured current in Amps |
- Source:
Returns:
Apparent Power in VA Promise will resolve to type number.
- Type
- Promise
CalculateThreePhasePower(voltage, lineTo, current) → {Promise}
Calcualte three phase power based on measured voltage and current
Parameters:
| Name | Type | Description |
|---|---|---|
voltage |
number | Measured voltage in Volts |
lineTo |
string | Which voltage was measured. Must be "line" or "netural" |
current |
number | Measured current in Amps |
- Source:
Returns:
Apparent Power in VA Promise will resolve to type number.
- Type
- Promise
ConvertPhaseAngleToPowerFactor(phaseAngle) → {Promise}
Convert from Phase Angle to Power Factor
Parameters:
| Name | Type | Description |
|---|---|---|
phaseAngle |
number | Phase Angle in degrees |
- Source:
Returns:
Power Factor Promise will resolve to type number.
- Type
- Promise
ConvertPowerFactorToPhaseAngle(powerFactor) → {Promise}
Convert from Power Factor to Phase Angle
Parameters:
| Name | Type | Description |
|---|---|---|
powerFactor |
number | Power Factor |
- Source:
Returns:
Phase Angle in degrees Promise will resolve to type number.
- Type
- Promise


io
.
gearpump
.
cluster
ClientToMaster
Related Doc:
package cluster
object
ClientToMaster
Application Flow
Linear Supertypes
AnyRef
,
Any
Ordering
Alphabetic
By inheritance
Inherited
ClientToMaster
AnyRef
Any
Hide All
Show all
Learn more about member selection
Visibility
Public
All
Type Members
case class
GetLastFailure
(
appId:
Int
)
extends
Product
with
Serializable
case class
GetStallingTasks
(
appId:
Int
)
extends
Product
with
Serializable
case class
JarStoreServerAddress
(
url:
String
)
extends
Product
with
Serializable
case class
QueryAppMasterConfig
(
appId:
Int
)
extends
Product
with
Serializable
case class
QueryHistoryMetrics
(
path:
String
,
readLatest:
Boolean
=
false
)
extends
Product
with
Serializable
case class
QueryWorkerConfig
(
workerId:
Int
)
extends
Product
with
Serializable
case class
ResolveAppId
(
appId:
Int
)
extends
Product
with
Serializable
case class
ResolveWorkerId
(
workerId:
Int
)
extends
Product
with
Serializable
case class
RestartApplication
(
appId:
Int
)
extends
Product
with
Serializable
case class
ShutdownApplication
(
appId:
Int
)
extends
Product
with
Serializable
case class
SubmitApplication
(
appDescription:
AppDescription
,
appJar:
Option
[
AppJar
]
,
username:
String
=
System.getProperty("user.name")
)
extends
Product
with
Serializable
Value Members
final
def
!=
(
arg0:
Any
)
:
Boolean
Definition Classes
AnyRef → Any
final
def
##
()
:
Int
Definition Classes
AnyRef → Any
final
def
==
(
arg0:
Any
)
:
Boolean
Definition Classes
AnyRef → Any
object
GetJarStoreServer
extends
Product
with
Serializable
object
QueryMasterConfig
extends
Product
with
Serializable
final
def
asInstanceOf
[
T0
]
:
T0
Definition Classes
Any
def
clone
()
:
AnyRef
Attributes
protected[
java.lang
]
Definition Classes
AnyRef
Annotations
@throws
(
...
)
final
def
eq
(
arg0:
AnyRef
)
:
Boolean
Definition Classes
AnyRef
def
equals
(
arg0:
Any
)
:
Boolean
Definition Classes
AnyRef → Any
def
finalize
()
:
Unit
Attributes
protected[
java.lang
]
Definition Classes
AnyRef
Annotations
@throws
(
classOf[java.lang.Throwable]
)
final
def
getClass
()
:
Class
[_]
Definition Classes
AnyRef → Any
def
hashCode
()
:
Int
Definition Classes
AnyRef → Any
final
def
isInstanceOf
[
T0
]
:
Boolean
Definition Classes
Any
final
def
ne
(
arg0:
AnyRef
)
:
Boolean
Definition Classes
AnyRef
final
def
notify
()
:
Unit
Definition Classes
AnyRef
final
def
notifyAll
()
:
Unit
Definition Classes
AnyRef
final
def
synchronized
[
T0
]
(
arg0: ⇒
T0
)
:
T0
Definition Classes
AnyRef
def
toString
()
:
String
Definition Classes
AnyRef → Any
final
def
wait
()
:
Unit
Definition Classes
AnyRef
Annotations
@throws
(
...
)
final
def
wait
(
arg0:
Long
,
arg1:
Int
)
:
Unit
Definition Classes
AnyRef
Annotations
@throws
(
...
)
final
def
wait
(
arg0:
Long
)
:
Unit
Definition Classes
AnyRef
Annotations
@throws
(
...
)
Inherited from
AnyRef
Inherited from
Any
Ungrouped
Application Flow


Finish migrate mntner {{ auth_mntner.rpsl_mntner_pk }}
in {{ auth_mntner.rpsl_mntner_source }}
{{ form_html }}
Finish the migration of your mntner by re-entering a current
password on the mntner and confirming the migration.
After this, you can authorise other users on the mntner.
Existing authentication methods will be kept,
but are discouraged.


{% extends "base.html" %} {% block content %}
Proceed to your email account to confirm your email address to activate your account


Device Info Class
EarthQuake!
Charlotte, Nakoruru
Apache Cordova
Connecting to Device
Device is Ready


Getting Started
The first step is to install DataMapper, then read all the topics in the General Topics section of the Table of Contents. You should read them in order as each topic builds on the previous one, and may include code examples that you are encouraged to try.
Once you understand the basics you'll be ready to explore the magic that is DataMapper. Below is a glimpse of what's to come!
Models
Here's a simple example of a few DataMapper models setup with relationships between each other. DataMapper models do the work of transforming your Database tables into easy to use objects. Further down in the Controllers section, you'll see just how easy it is to use them.
User
<?php
class User extends DataMapper {
var $has_many = array('book');
var $has_one = array('country');
var $validation = array(
array(
'field' => 'username',
'label' => 'Username',
'rules' => array('required', 'trim', 'unique', 'alpha_dash', 'min_length' => 3, 'max_length' => 20),
),
array(
'field' => 'password',
'label' => 'Password',
'rules' => array('required', 'trim', 'unique', 'min_length' => 6, 'encrypt'),
),
array(
'field' => 'confirm_password',
'label' => 'Confirm Password',
'rules' => array('encrypt', 'matches' => 'password'),
),
array(
'field' => 'email',
'label' => 'Email Address',
'rules' => array('required', 'trim', 'valid_email')
)
);
function User()
{
parent::DataMapper();
}
function login()
{
// Create a temporary user object
$u = new User();
// Get this users stored record via their username
$u->where('username', $this->username)->get();
// Give this user their stored salt
$this->salt = $u->salt;
// Validate and get this user by their property values,
// this will see the 'encrypt' validation run, encrypting the password with the salt
$this->validate()->get();
// If the username and encrypted password matched a record in the database,
// this user object would be fully populated, complete with their ID.
// If there was no matching record, this user would be completely cleared so their id would be empty.
if (empty($this->id))
{
// Login failed, so set a custom error message
$this->error_message('login', 'Username or password invalid');
return FALSE;
}
else
{
// Login succeeded
return TRUE;
}
}
// Validation prepping function to encrypt passwords
// If you look at the $validation array, you will see the password field will use this function
function _encrypt($field)
{
// Don't encrypt an empty string
if (!empty($this->{$field}))
{
// Generate a random salt if empty
if (empty($this->salt))
{
$this->salt = md5(uniqid(rand(), true));
}
$this->{$field} = sha1($this->salt . $this->{$field});
}
}
}
/* End of file user.php */
/* Location: ./application/models/user.php */
Country
<?php
class Country extends DataMapper {
var $table = 'countries';
var $has_many = array('user');
var $validation = array(
array(
'field' => 'name',
'label' => 'Country',
'rules' => array('required', 'trim', 'unique', 'alpha_dash', 'min_length' => 1, 'max_length' => 50),
)
function Country()
{
parent::DataMapper();
}
}
/* End of file country.php */
/* Location: ./application/models/country.php */
Book
<?php
class Book extends DataMapper {
var $has_many = array('user');
var $validation = array(
array(
'field' => 'title',
'label' => 'Title',
'rules' => array('required', 'trim', 'unique', 'alpha_dash', 'min_length' => 1, 'max_length' => 50),
),
array(
'field' => 'description',
'label' => 'Description',
'rules' => array('required', 'trim', 'alpha_slash_dot', 'min_length' => 10, 'max_length' => 200),
),
array(
'field' => 'year',
'label' => 'Year',
'rules' => array('required', 'trim', 'numeric', 'exact_length' => 4),
)
);
function Book()
{
parent::DataMapper();
}
}
/* End of file book.php */
/* Location: ./application/models/book.php */
Controllers
Here's a quick example of a Controller handling the creation of a user, setting up and accessing some related objects, and logging a user in. To keep it simple, we'll echo the results from the Controller rather than setting up a View.
Users
<?php
class Users extends Controller {
function Users()
{
parent::Controller();
}
function index()
{
// Let's create a user
$u = new User();
$u->username = 'Fred Smith';
$u->password = 'apples';
$u->email =<EMAIL_ADDRESS>// And save them to the database (validation rules will run)
if ($u->save())
{
// User object now has an ID
echo 'ID: ' . $u->id . '
';
echo 'Username: ' . $u->username . '
';
echo 'Email: ' . $u->email . '
';
// Not that we'd normally show the password, but when we do, you'll see it has been automatically encrypted
// since the User model is setup with an encrypt rule in the $validation array for the password field
echo 'Password: ' . $u->password . '
';
}
else
{
// If validation fails, we can show the error for each property
echo $u->error->username;
echo $u->error->password;
echo $u->error->email;
// or we can loop through the error's all list
foreach ($u->error->all as $error)
{
echo $error;
}
// or we can just show all errors in one string!
echo $u->error->string;
// Each individual error is automatically wrapped with an error_prefix and error_suffix, which you can change (default:
error message
)
}
// Let's now get the first 5 books from our database
$b = new Book();
$b->limit(5)->get();
// Let's look at the first book
echo 'ID: ' . $b->id . '
';
echo 'Name: ' . $b->title . '
';
echo 'Description: ' . $b->description . '
';
echo 'Year: ' . $b->year . '
';
// Now let's look through all of them
foreach ($b->all as $book)
{
echo 'ID: ' . $book->id . '
';
echo 'Name: ' . $book->title . '
';
echo 'Description: ' . $book->description . '
';
echo 'Year: ' . $book->year . '
';
echo '
';
}
// Let's relate the user to these books
$u->save($b->all);
// Yes, it's as simple as that! You can add relations in several ways, even different types of relations at the same time
// Get the Country with an ID of 10
$c = new Country();
$c->where('id', 10)->get();
// Get all Books from the year 2000
$b = new Book();
$b->where('year', 2000)->get();
// Relate the user to them
$u->save(array($c, $b->all));
// Now let's access those relations from the user
// First we'll get all related books
$u->book->get();
// You can just show the first related book
echo 'ID: ' . $u->book->id . '
';
echo 'Name: ' . $u->book->title . '
';
echo 'Description: ' . $u->book->description . '
';
echo 'Year: ' . $u->book->year . '
';
// Or if you're expecting more than one, which we are, loop through all the books!
foreach ($u->book->all as $book)
{
echo 'ID: ' . $book->id . '
';
echo 'Name: ' . $book->title . '
';
echo 'Description: ' . $book->description . '
';
echo 'Year: ' . $book->year . '
';
echo '
';
// And there's no need to stop there,
// we can see what other users are related to each book! (and you can chain the get() of related users if you don't want to do it on its own, before the loop)
foreach ($book->user->get()->all as $user)
{
// Show user if it's not the original user as we want to show him the other users
if ($user->id != $u->id)
{
echo 'User ' . $user->username . ' also likes this book
';
}
}
}
// We know there was only one country so we'll access the first record rather than loop through $u->country->all
// Get related country
$u->country->get();
echo 'User is from Country: ' . $u->country->name . '
';
// One of the great things about related records is that they're only loaded when you access them!
// Lets say the user no longer likes the first book from his year 2000 list, removing that relation is as easy as adding one!
// This will remove the users relation to the first record in the $b object (supplying $b->all would remove relations to all books in the books current all list)
$u->delete($b);
// You can delete multiple relations of different types in the same way you can save them
// Now that we're done with the user, let's delete him
$u->delete();
// When you delete the user, you delete all his relations with other objects. DataMapper does all the tidying up for you :)
}
function register()
{
// Create user object
$u = new User();
// Put user supplied data into user object
// (no need to validate the post variables in the controller,
// if you've set your DataMapper models up with validation rules)
$u->username = $this->input->post('username');
$u->password = $this->input->post('password');
$u->confirm_password = $this->input->post('confirm_password');
$u->email = $this->input->post('email');
// Attempt to save the user into the database
if ($u->save())
{
echo '
You have successfully registered
';
}
else
{
// Show all error messages
echo '
' . $u->error->string . '
';
}
}
function login()
{
// Create user object
$u = new User();
// Put user supplied data into user object
// (no need to validate the post variables in the controller,
// if you've set your DataMapper models up with validation rules)
$u->username = $this->input->post('username');
$u->password = $this->input->post('password');
// Attempt to log user in with the data they supplied, using the login function setup in the User model
// You might want to have a quick look at that login function up the top of this page to see how it authenticates the user
if ($u->login())
{
echo '
Welcome ' . $u->username . '!
';
echo '
You have successfully logged in so now we know that your email is ' . $u->email . '.
';
}
else
{
// Show the custom login error message
echo '
' . $u->error->login . '
';
}
}
}
/* End of file login.php */
/* Location: ./application/controllers/login.php */
Cool huh?
I hope that's enough to wet your appetite! It's hard to show the full benefits of DataMapper in one simple page but I'm sure you've glimpsed the power DataMapper can give you and in such a simple and logical way!
Please continue on with the General Topics to learn more.


To minimize abuse, we only allow users to adjust their monthly budgets once every 3 months.
Please confirm intention to delete account by typing “DELETE” in the text field and then hit the button


Company name -
Issue price - / share
Lot size - / lot
NII subscription detail -
Listing day price -
Minimum shares to apply - {{minSharesApplied}}> Minimum investment amount - {{minInvestmentAmount}}>
Total investment amount -
Loan amount - at % pa
Personal amount -
days for redemption of unallotted cash -
days for listing -
shares applied - {{sharesApplied}}
total shares allocated - {{sharesAllocated}} (INR {{sharesAllocated*issuePrice}})
total profit - {{totalProfit}}


{% extends "base.html" %} {% import 'bootstrap/wtf.html' as wtf %} {% block app_content %}
You can borrow books here.
Select the books that you want to borrow.


siddh [at] cs [dot] uw [dot] edu
Administrative Assistant
Lisa Merlin
lmerlin [at] cs [dot] washington [dot] edu
Ph: +1<PHONE_NUMBER>
Office
CSE572,
Paul G. Allen School of Computer Science & Engineering,
University of Washington,
Box 352350,
Seattle WA 98195-2350


Hey !
This week I worked on implementing a method for finding the range of a function in a given domain. Following from last weeek’s research on the same, I tried to develop these utility functions.
Implementation Link to heading
Here, I have defined the two functions along with some of their implementation details:
continuous_in(f, x, interval)
The function returns the sub-domains as an Union
of Interval
in case a discontinuity exists in the interval
. If the function is continuous in the entire domain, the interval
itself is returned.
For this we need to consider 2 primary conditions:
-
Domain constraints for real functions I have also added some code for domain constraints in
sqrt
andlog
functions. Using thesolve_univariate_inequality
method (as the name suggests, it solves univariate inequalities), we calculate these constraints.
Givenf(x) = sqrt(g(x))
, we determine the range of values ofx
for which the functiong(x) >= 0
.
Similarly, forf(x) = log(g(x))
, the interval ofx
in whichg(x) > 0
is the constrained interval. -
Singularities For determining the discontinuities, I tried to solve the reciprocal of the given function using
solveset
:solveset(1/f, x, interval)
. Thesingularities
function can also be used here but its implementation is restricted to rational functions only. There are possibilities of improving this function to create a universal function which returns all the possible singularities of the function in a given domain.
function_range(f, x, domain)
Like the name suggests, this method returns the range of a univariate function in a given domain. This function is primarily designed for the purpose of solve_decomposition
.
This function calls the above implemented continuous_in
method for finding the actual domain of f
. Following this, we iterate over each Interval
object returned by continuous_in
.
By using the boundaries of the interval and first derivate test, we determine the crtical points in the interval and their corresponding critical values.
For determining the values of the function at the singularities, we determine its limit at that point.
For this, I use the limit
function of SymPy.
After calculating the local extremas, I calculate the global minima and maxima using the inf
(infimum) and sup
(supremum) of the FiniteSet
of all critical values. The range, which is the Interval
of these extremasm, is returned.
$ git log Link to heading
PR#11141: Method for solving equations using Decomposition and Rewriting
Opened this week
PR#11224: Methods for finding the range of a function in a given domain
Final Thoughts
That was all for this week.
My task for the upcoming days would be to update my solve_decomposition
method to accomodate these methods.
I aim to get all these PR merged before the midterm evaluation.


| Class | Description |
|---|---|
| Bid |
Bid model contains all the features of a single bid
|
| BidCounter |
Detail: BidCounter is used to record how many bids the requester have ever got.
|
| BidTest |
This is the test class for bid methods.
|
| BuildConfig | |
| ExampleUnitTest |
Example local unit test, which will execute on the development machine (host).
|
| OfflineTest |
This is the test class for offline handling methods.
|
| Photo |
Photo class contains information for an array of base string64 bitmaps.
|
| photoTest |
This is the test for photo handling methods.
|
| R | |
| R.anim | |
| R.animator | |
| R.attr | |
| R.bool | |
| R.color | |
| R.dimen | |
| R.drawable | |
| R.id | |
| R.integer | |
| R.layout | |
| R.mipmap | |
| R.string | |
| R.style | |
| R.styleable | |
| Task |
Task model contains all the features of a task.
|
| TaskTest | |
| User |
User object contains all the features of a user.
|
| UserTest |
This is the user test
|


Hint: Say "Change square/circle color to" ...then say a color (red, blue, green, yellow, or black)
Hint: Say "clear the text" if things are getting too long
Hint: Say "find me a" to search google images


Starlets Arrive In Tanzania For Cecafa Women’s Championship After Olympics Disappointment (Photos)
by Bonface OsanoKenya women’s national, the Harambee Starlets, arrived in Dar, Tanzania on Wednesday ahead of the CECAFA Women Championships starting this weekend.
The team left the country earlier this morning and will play their opener against Ethiopia on Sunday.
Despite bidding the 2020 Tokyo Olympics qualifiers goodbye after being knocked out by Zambia on Monday, the head coach, David Ouma, appreciated the team for their efforts.
“We didn’t get the results we anticipated in the Olympics Qualifiers but nonetheless, the girls gave a good account of themselves and I must say I am proud of them,” said Coach David Ouma.
He added: “There are a lot of positives to be picked and it’s now time to apply the lessons learnt.”
Kenya has been pooled in group B alongside Uganda, Ethiopia, and Djibouti. Group A comprises of Tanzania, Burundi, Zanzibar, and South Sudan.
The top two teams from each group will proceed to the semifinals.
Fixtures
Burundi vs Zanzibar (Saturday, November 16, 2019, Chamazi, 2 pm)
Tanzania vs South Sudan (Saturday, November 16, 2019, Chamazi, 4.30 pm)
Ethiopia vs Kenya (Sunday, November 17, 2019, Chamazi, 2 pm)
Uganda vs Djibouti (Sunday, November 17, 2019, Chamazi, 4.30 pm)
South Sudan vs Zanzibar (Monday, November 18, 2019, Chamazi, 2 pm)
Burundi vs Tanzania (Monday, November 18, 2019, Chamazi, 4.30 pm)
Kenya vs Djibouti (Tuesday, November 19, 2019, Chamazi, 2 pm)
Uganda vs Ethiopia (Tuesday, November 19, 2019, Chamazi, 4.30 pm)
South Sudan vs Burundi (Wednesday, November 20, 2019, Chamazi, 2 pm)
Zanzibar vs Tanzania (Wednesday, November 20, 2019, Chamazi, 4.30 pm)
Djibouti vs Ethiopia (Thursday, November 21, 2019, Chamazi, 2 pm)
Kenya vs Uganda (Thursday, November 21, 2019, Chamazi, 4.30 pm)
Semifinals
Winner Group A vs Runners-up Group B (Saturday, November 23, 2019, Chamazi, 2 pm)
Winner Group B vs Runners-up Group A (Saturday, November 23, 2019, Chamazi, 4.30 pm)
Finals
Third place Playoff (Monday, November 25, 2019, Chamazi, 2 pm)
Final (Monday, November 25, 2019, Chamazi, 4.30 pm).


{% extends "base.html" %} {% block title %}
Medieval catalogues > UNIVERSITY AND COLLEGE LIBRARIES OF OXFORD > Merton College > Catalogue of theological books, 1349–c. 1360
{% endif %}206 identified entries found.
All data was derived from the List of Identifications by Professor Richard Sharpe.
{% if not printing %}
A key to codes used in the List is available (opens in new tab).{% endif %}


{% load static %}
Wanna Make a Visit to Our Site ??
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
There are many variations of passages of Lorem Ipsum available.
Overview We're a group of women who want to learn JavaScript.


DSC - GTBIT
Home
(current)
Team
Projects
Events
Learn
Meet The Team
Passionate students and faculty staff driving the success of the program.


Affiliation Analysis Radar Chart Add Radar Chart to Doc Bar Chart Add Radar Chart to Doc Add Comments About Charts


#assign n0_releases="active">
See the project github releases for details of the released versions.
Help the Ebean project maintain releases and documentation.
Every donation helps the project maintain a high level of quality in both code and documentation and donations help the ongoing effort.
$Donate
View the latest artifacts for io.ebean
in
maven central.
Past versions of Ebean artifacts where released using the groupId: org.avaje.ebean
and
prior to that org.avaje.ebeanorm
.
These artifacts can be found here
and here.
In moving to the io.ebean
groupId the artifactId's where changed to follow a simpler
naming convention.
| New artifactId | Old artifactId |
|---|---|
| ebean | avaje-ebeanorm |
| ebean-agent | avaje-ebeanorm-agent |
| ebean-mocker | avaje-ebeanorm-mocker |
| ebean-maven-plugin | avaje-ebeanorm-mavenenhancer |
| ebean-querybean | avaje-ebeanorm-querybean |
| ebean-hazelcast | avaje-ebeanorm-hazelcast |
| ebean-ignite | avaje-ebeanorm-ignite |
| ebean-elastic | avaje-ebeanorm-elastic |
| ebean-spring | avaje-ebeanorm-spring |
| ebean-jackson | avaje-ebeanorm-jackson |
| ebean-cluster | avaje-ebeanorm-cluster |


Kevin J Black
Winter Trails of the Wasatch
HTML, CSS, JavaScript
Home
Millcreek Canyon
Big Cottonwood Canyon
Little Cottonwood Canyon
Gear
Men's Clothing
Black Diamond
Women's Clothing
Black Diamond
Snowshoes at REI
Poles at REI
Hydration packs at REI
Beacons at REI
Things to consider from snowshoemag.com
Millcreek Canyon
Desolation Trail to Scenic Overlook
Winter Road to the Big Winter Yurt
(Winter Gate along East Millcreek Canyon Road)
Big Cottonwood Canyon
Days Fork
Mill D South to Doughnut Falls
Days Fork Trail to Green Basin
Brighton: Silver Lake
Brighton: Silver Lake to Solitude Lake Trail
Brighton: Silver Lake Twin Lakes Trail
Little Cottonwood Canyon
Albion Basin Road to Cecret Lake
Albion Basin Road to Catherine Pass or Sunset Peak
Maybird Lake Trail
Red Pine Trail
White Pine Lake Trail


|
| Local Properties | ||
| Managed Object Types | Data Object Types | All Properties | All Methods |
Properties
| Name | Type | Description |
|---|---|---|
| autoExpand* | xsd:boolean |
If set to true, this property ignores the limit on the number of ports in the
portgroup. When a Virtual Machine/Host tries to connect to the portgroup and there
are no free ports available in the portgroup, new ports will be automatically
added to the portgroup. The flag is currently supported only for static portgroups.
Setting this property to true makes the portgroup a potential candidate for auto-shrink. Once the portgroup has auto-expanded then its disconnected ports are likely to be deleted automatically, as a part of auto-shrink step, if there are more than certain number of free ports. If the portgroup never auto-expanded, then it will never lose any free ports. Since vSphere API 5.0 |
| configVersion* | xsd:string |
Version string of the configuration that this spec is trying to
change. This property is required in reconfiguring a portgroup and
should be set to the same value as the
configVersion.
This property is ignored in creating a portgroup if set.
|
| defaultPortConfig* | DVPortSetting |
Default network setting for all the ports in the portgroup.
|
| description* | xsd:string |
Description of the portgroup.
|
| name* | xsd:string |
Name of the portgroup.
|
| numPorts* | xsd:int |
Number of ports in the portgroup. Setting this number larger than the
number of existing ports in the portgroup causes new ports to
be added to the portgroup to meet the number. Setting this property
smaller than the number of existing ports deletes the free ports
from the portgroup. If the number cannot be met by deleting free ports,
a fault is raised. If new ports are added to the portgroup, they
are also added to the switch. For portgroups of type ephemeral this
property is ignored.
|
| policy* | DVPortgroupPolicy |
Portgroup policy.
|
| portNameFormat* | xsd:string |
Format of the name of the ports when ports are created in the portgroup.
For details see portNameFormat.
|
| scope* | ManagedObjectReference[]
to a ManagedEntity[] | Deprecated.
as of vSphere API 5.5
Eligible entities that can connect to the port. See
DVPortgroupConfigInfo.scope.
|
| type* | xsd:string |
Type of portgroup.
See
DistributedVirtualPortgroup.DistributedVirtualPortgroupPortgroupType
for possible values.
|
| vendorSpecificConfig* | DistributedVirtualSwitchKeyedOpaqueBlob[] |
Opaque binary blob that stores vendor specific configuration.
|
| vmVnicNetworkResourcePoolKey* | xsd:string |
The key of virtual NIC network resource pool to be associated with a portgroup.
Setting this property to "-1", would mean that this portgroup
is not associated with any virtual NIC network resource pool.
Since vSphere API 6.0 |
| Properties inherited from DynamicData | ||
| None |
| Top of page | Local Properties | ||
| Managed Object Types | Data Object Types | All Properties | All Methods |


{% extends "parent.html" %} {% block title %} Card List {% endblock %} {% block body %}
There are no cards in the deck.


|
The privacy policy below explains in detail how information is collected about our users. Privacy is taken very seriously. StudyLight.org won't rent, sell, or loan any information about you. You're safe with StudyLight.org.
StudyLight.org considers your trust and right to privacy paramount. The following privacy policy outlines for your review the type of information which is gathered - and how it is used - from members, and visitors of www.studylight.org and related areas (email subscriptions).
two types of information are gathered:
- Membership data, which you provide directly in order to participate in certain services or site areas and which may or may not require both demographic information (name, email address, and so on) and preference information (username, password, desired email subscriptions, and so on),
- Usage information, which is automatically provided by each user's browser for each page requested on our site (commonly referred to as web site log data).
membership data
This is strictly for internal use and is not provided to any third parties such as advertisers. StudyLight.org will not disclose any individual user's name, e-mail address without such user's prior consent, except to the extent necessary or appropriate to comply with applicable laws or in legal proceedings where such information is relevant.
StudyLight.org does not knowingly accept or use personal profile information from children 12 years old
or younger.
usage (log) data
StudyLight does gather and analyze users' current Internet Protocol (IP) addresses -- an address typically assigned to individual browsers by your Internet Service Provider (ISP) -- to help with a variety of site management issues, none of which allow for connecting your IP address with your personal identity. For example, log data is used to:
- diagnose server problems,
- evaluate the sources of user traffic (ie. where visitors clicked from to reach the site),
- determine traffic patterns through the site (to build better internal links and improve visitors ability to find what they want),
- understand and optimize the site for the broadest selection of browser types (again, to improve your experience).
cookies
The site uses cookies to improve your experience while you're visiting. Cookies are electronic "nametag" placed on your browser to help the servers recognize you; while you're on the site, cookies help insure things like:
- you can get customized (ie. selected by you) information without having to ask for it every visit,
- you only have to log-in once - when it's even necessary - when you visit certain "members-only" areas,
Finally, cookies do not provide StudyLight.org with information about who you are or where you go on the Internet when you are not at our site.
opt-in
StudyLight.org acquires no personal or registration data about our users except what you explicitly and voluntarily provide (ie. membership or opt-in). We reserve the right to use this information specifically for the purposes related to your registration and generally for any necessary future communication regarding your registration or status.
As part of your subscription, from time to time we will deliver messages from the ministry that might be of specific interest to you.
correcting and updating User registration data can be corrected or updated by using our convenient contact form
delete/deactivate
You may also use our convenient contact form to deactivate an account or delete an account and have it removed from our database.
|
Make A Difference, Today!
Lectionary Calendar
Saturday, August 6th, 2016 the Week of Proper 13 / Ordinary 18
ADVERTISEMENT
|


{% extends "employee_base.html" %} {% block title %} Employee Contact Information {% endblock %} {% block employee_content %}
| First Name | Last Name | Phone Number | Employee ID | Position | Manager | Add New | ||
| {{employee.first_name}} | {{employee.last_name}} | {{employee.phone_number}} | {{employee.email_address}} | {{employee.emp_code}} | {{employee.position}} | {{employee.manager_name}} |


Video: Napoleon Opening Credits
Albin Merle shares an incredible-looking 'fake' trailer for a television show about Napoleon Bonaparte.
Here is a fake opening credits i did recently as i wanted to improve my 3dskills and explore a new workflow for cutting edge trailer.
Like if a massive production company would decide to make a series on Napoleon. Most of the model are inspired from the online collection of the French army museum of invalides. (musée de l’armée des invalides ).
Cou can download the free Coin 3d model here.
A few words about the workflow:
Modeling in blender, texturing in substance painter. I used a decimated lowpoly model to rig my model into mixamo, then imported in back into blender to transfer my rig onto the Highpoly model. Whenever a model is duplicated, i use as much as possible the Linked file tool to keep my scene light.
For instance, in the shot with several soldiers i just append the collection and offset the animation.
Cycles for rendering.
Music : Lacrimosa, Mozart.
hope you guys will like it.


Enables linking on Windows without having to link to the real implementations Only for unit testing.
Utility functions for writing XLLs
MemoryManager.D
Only exists to test the wrapping functionality Contains functions with regular D types that will get wrapped so they can be called by the spreadsheet.
Only exists to test the module reflection functionality Contains functions with types that the spreadsheet knows about
This module implements the compile-time reflection machinery to automatically register all D functions that are eligible in a compile-time define list of modules to be called from Excel.
Interface for registering worksheet functions with Excel
Wraps calls to xlXXX "functions" via the Excel4/Excel12 functions
Microsoft Excel Developer's Toolkit Version 15.0
Microsoft Excel Developer's Toolkit Version 14.0


Sign-Up
Name
Email address
Password
Date of Birth
Address
Sign-Up
{% if error %}
There was an error. Please try again later.
{% endif %}
Log in


Creates extruded geometry from a path shape.
const length = 12, width = 8;
const shape = new THREE.Shape();
shape.moveTo( 0,0 );
shape.lineTo( 0, width );
shape.lineTo( length, width );
shape.lineTo( length, 0 );
shape.lineTo( 0, 0 );
const extrudeSettings = {
steps: 2,
depth: 16,
bevelEnabled: true,
bevelThickness: 1,
bevelSize: 1,
bevelOffset: 0,
bevelSegments: 1
};
const geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings );
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const mesh = new THREE.Mesh( geometry, material ) ;
scene.add( mesh );
shapes — Shape or an array of shapes.
options — Object that can contain the following parameters.
This object extrudes a 2D shape to a 3D geometry.
When creating a Mesh with this geometry, if you'd like to have a separate material used for its face and its extruded sides, you can use an array of materials. The first material will be applied to the face; the second material will be applied to the sides.
See the base [page:BufferGeometry] class for common properties.
An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
See the base [page:BufferGeometry] class for common methods.
[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]


Why having a growth plan is important for your business
by Raheem AdebayoThere are many reasons why having a growth plan is beneficial to your business, especially in tough economic circumstances. You can be sure that your competitors will be looking to obtain your customers or your share of the market, and in the absence of a growth plan, many businesses suffer from severe knock-on effects that impact revenue growth. Building and sharing a growth plan with your team and external advisors ensures that you are sprinting in the correct direction of customer segments that most value your offerings.
Here are some issues that lack of a growth plan leads to:
- delaying your growth;
- wasted efforts;
- no Sensible Target;
- lack of Accountability;
- no New Thinking;
- poor Execution;
- intense Competition; and
- lack of Learning from Execution.
Before attempting to expand your business, you need to take time to document your growth strategy. With a well-thought-out and documented strategy in place, you can ensure that your business growth is led by informed decisions, thereby avoiding surprise pitfalls that compromise profits.
What is a growth strategy?
In the simplest sense, a growth strategy is a document that details your business goals and defines your strategies for meeting those goals. It’s a road map detailing the goals you’re striving to meet, how you’re planning to meet them, and when you’re planning to execute.
The most effective strategies are documented so that they can be shared across the organization. Having a documented strategy creates cohesiveness, allowing decisions and initiatives across the company to be catered to established goals. While initial planning is crucial, iterative planning is important as well. By revisiting your strategy at regular intervals, you can make strategic shifts based on new information, market changes and historical data.
[READ MORE: Steps to investing]
Business growth strategies
There are many ways to grow a business. Which way you choose to expand largely depends on your ambition, your reasons for growth, and the opportunities and resources available. However, two crucial factors for choosing a business growth strategy exist. They are:
- Products – what you currently offer, and what you’d like to offer in the future
- Markets – where you currently sell, and where you’d like to sell in the future
Based on these factors, strategic tools—such as the Ansoff matrix—suggest four main types of business growth strategies.
What are the four major growth strategies?
In the simplest terms, there are four possible strategies for growth, each with its own distinct risks. These are:
- market penetration;
- product development;
- market development; and
- diversification.
With market penetration, you try to sell more of the same things to the same market. The risks are usually low as you focus on capturing a bigger share of your current market with the products you already have.
Market penetration tactics
To devise a good market penetration strategy, you must have a successful product and a detailed knowledge of your market. You must also thoroughly understand your competitors.
You can usually achieve market penetration in four ways. You can:
- increase the market share of current products;
- increase usage by existing customers;
- dominate growth markets; and
- drive out competitors from a saturated market.
Product development
With product development, you are introducing a new product into your existing market. You’re effectively selling something different to the same customer, potentially encountering greater risks. With product development, a business usually has one of three choices. You can:
- create an entirely new product;
- evolve your existing product for its existing market; and
- enhance your existing product to introduce it to new markets.
Market development
Another option is market development, where you try to sell an existing product in a brand new market. For example, you may want to segment your existing market or reposition your product in it or target an entirely different geographical area. Market development is a growth strategy that involves selling your existing products or services to a new group of customers. It begins with market research where you:
- carry out a segmentation analysis of your existing market; and
- shortlist those market segments which you feel you should pursue.
Key market development strategies you could consider focus on:
- Pricing: You could implement competitive price structures with offers and discounts or, to command a higher price, provide a product with more value than the competitor’s.
- Distribution: You could develop new channels to reach target customers, e.g. sell online if you currently only have a brick and mortar shop.
- Branding: You could create a new brand for products aiming to reach a target market or a specific customer segment.
- Promotion: You could consider tailoring promotional messages to entice customers with offers, vouchers, loyalty schemes, etc.
- Sales: You could target a different demographic segment or type of customer to create new leads and opportunities.
- Product development: You can alter an existing product or develop a new one for the untapped market
Diversification
Finally, with diversification, you are aiming to sell completely different goods or services to completely different customers. This is typically the riskiest of options; it requires both product and market development.
Conclusion
Starting and growing a business requires a significant amount of time, effort and planning. Quick decisions and big investments may be appealing, but unless they translate into functional and sustainable business models, the temporary excitement can lead to very public disappointment.
Before you take steps to grow your business, you need to document your growth strategy. The research and documentation will take time, but the upfront investment will pay off in the end. Keep in mind that to succeed, your growth strategy has to be deliberate. Success will require a great deal of research and thorough planning for business growth.


Per ORCID's terms of use, you may only register for an ORCID iD for yourself. Already have an ORCID iD? Sign In


Ethereum Account Information
Show Balance
Address List
Add Address
Name
Address
Name
Chain
Mainnet
Ropsten
Rinkeby
Kovan
Ethererum Address
Add Address
add


§291-11 Riders and passengers under seven years of age on motorcycles and motor scooters prohibited; penalty. (a) It shall be unlawful for any driver of a motorcycle or motor scooter to carry as a passenger or to permit to ride thereon any person under the age of seven years.
(b) A driver of a motorcycle or motor scooter shall be permitted to carry as a passenger or permit to ride thereon any person under the age of seven years; provided that the motorcycle or motor scooter:
(1) Has three wheels;
(2) Is powered by an electric motor;
(3) Has a full body enclosed cab; and
(4) Has a seat belt assembly or a child restraint system for the driver and passenger;
and the operator and passenger uses the seat belt or child restraint system pursuant to sections 291-11.5 and 291-11.6.
(c) A motorcycle or motor scooter driver who violates this section shall be fined not more than $200. [L 1967, c 214, §20; HRS §291-11; am L 1968, c 48, §4; am L 1970, c 164, §3; am L 1994, c 120, §3]
Cross References
Riding on motorcycles, see §291C-152.


Home
Contact
Home
Contact
I am a software engineer with a passion for designing web sites. Scroll through to view a collection of my work.
Scroll for projects
HNM 237
A not for profit organisation
Douala Tees
A personalised clothing brand
Mohmanyang
A literary blog
Kingsway
A cleaning contractor
Hiya!
Need a website?
Get in touch


Module display
Tables
| texture | Render using a texture. |
| mesh | Render using a mesh. |
| gpux | Render exclusively on the GPU. |
Class Tesselator
| tove.newAdaptiveTesselator (resolution[, recursionLimit]) | Create an adaptive tesselator. |
| tove.newRigidTesselator (subdivisions) | Create a rigid tesselator. |
Tables
- texture
-
Render using a texture.
Also see the TÖVE Feature Matrix.
Fields:
- mode
string
"texture"
See also:
Usage:
graphics:setDisplay("texture")
- mode
string
- mesh
-
Render using a mesh.
If no tesselator is specified, a default tesselator will be chosen based on the configured
usage of the Graphics.
Also see the TÖVE Feature Matrix.
Fields:
- mode
string
"mesh"
- tesselator Tesselator, string or number tesselator to use or name of tesselator type or target size (optional)
- args ... configuration of tesselator (optional)
See also:
Usage:
graphics:setDisplay("mesh") -- default configuration (based on configured usage) graphics:setDisplay("mesh", 1024) -- make it look good at a size of 1024 pixels -- will choose tesselation settings based on configured usage graphics:setDisplay("mesh", "rigid", 4) -- 4 subdivision levels (=2^4 points per curve) graphics:setDisplay("mesh", tove.newRigidTesselator(4)) -- same as above graphics:setDisplay("mesh", "adaptive", 1024) -- target a size of 1024 graphics:setDisplay("mesh", tove.newAdaptiveTesselator(1024)) -- same as above
- mode
string
- gpux
-
Render exclusively on the GPU.
"gpux"
means "gpu exclusive": this mode will implicitly render all curve geometry on the fly on the GPU. This has considerable resolution until it breaks down, however it can also be quite expensive in terms of performance (note also that it needs one GL context change per path). It is quite experimental as well: TÖVE is - to the best of my knowledge - the first library capable of rendering complex cubic bezier shapes inside GLSL shaders without doing some kind of tesselation. The only other existing implementation with this kind of approach seems to be NVidia™'s GPU Accelerated Path Rendering. Also see the TÖVE Feature Matrix.Fields:
- mode
string
"gpux"
- lineRenderer
string
line shader (
"fragment"
or"vertex"
). use"fragment"
for lines that need to have round edges, use"vertex"
for lines that need to have miters. You can use demos/editor to get an idea of the differences of this setting for various geometries. (default "fragment") - lineQuality
number
line quality (between 0 and 1). Higher numbers are
slower (
"fragment"
lines) or generate more geometry ("vertex"
lines). (default 1)
See also:
Usage:
graphics:setDisplay("gpux") graphics:setDisplay("gpux", "vertex") -- use vertex shader for line drawing
- mode
string
Class Tesselator
- tove.newAdaptiveTesselator (resolution[, recursionLimit])
-
Create an adaptive tesselator.
Use this for high quality static graphics content that does not animate its shape in realtime.
Adaptive Tesselators create meshes that give more subdivision (i.e. points and triangles) to areas where
higher detail is needed, whereas other areas might get less subdivision. The number of vertices produced by
Adaptive Tesselators depends on the specific geometry. They are not suited for shape animation, as each shape
change would result in a different number of vertices and triangles.
Parameters:
- resolution number resolution at which the mesh should look good
- recursionLimit int maximum number of recursions during subdivision (optional)
- tove.newRigidTesselator (subdivisions)
-
Create a rigid tesselator.
Use this to obtain low or medium quality meshes that can distort and animate their shapes in realtime.
Rigid tesselators subdivide geometry using fixed steps and thus produce a fixed number of vertices. As an
effect, all areasy of the geometry receive the same level of detail and subdivision. They are suited for
shape animation, as the vertex count stays constant and underlying meshes can be updated efficiently.
Parameters:
- subdivisions int number of recursive subdivisions; 3 means 2^3=8 points for each bezier curve, 4 indicates 2^4=16 points, and so on.


| Retriev (Canada) |
Cryo-hydrometallurgy |
Li |
| Umicore (Belgium) |
Pyro-hydrometallurgy |
Co, Ni, and Mn |
| Sumimoto (Japan) |
Pyro-hydrometallurgy |
Cu, and Ni |
| Recupyl (France) |
Hydrometallurgy |
Li, Co, Ni, Mn, Cu, and Al |
| Snam (France) |
Pyrometallurgy |
Cd, Ni, Co, and Fe |
| Accurec (Germany) |
Pyrometallurgy |
Al, Cu, Co, Ni, and Fe |
| Glencore (Canada) |
Pyro-hydrometallurgy |
Ni, and Co |
| Batrec (Switzerland) |
Pyro-hydrometallurgy |
Zn, Co, Ni, Mn, and Hg |
| AkkuSer Oy (Finland) |
Mechanical |
LIB active materials |
| OnTo Technology (USA) |
Direct Recycling |
LIB active materials |
| Dowa (Japan) |
Pyrometallurgy |
Co, Ni, and Mn |
| Nickelhütte Aue Gmbh (Germany) |
Pyrometallurgy |
Co, Ni, and Mn |
| Brunp (China) |
Pyro- and hydrometallurgy |
Li, Co, Ni, Mn, Cu, and Al |


{% extends 'base.html' %} {% block content %} {% include 'disty/navigation.html' %}
Downloaded files from links created by {{ user }}:
| Date | From IP | File URL | file name |
|---|---|---|---|
| {{ access.timestamp }} | {{ access.source_ip }} | {{ access.url }} | {{access.file }} |
| {{ access.timestamp }} | {{ access.source_ip }} | {{ access.url }} | {{access.file }} |


I always wanted to skip this ones
What they are and why do we need them
A little bit of history, and a photo of Linus
Using command line, help and stuff.
The basic commands, when to use them and all of that