Create an additional staging environment that closely resembles the
production one
Keep any additional configuration in YAML files under the config/ directory
Rails::Application.config_for(:yaml_file)
Use nested routes to express better the relationship between ActiveRecord
models
nest routes more than 1 level deep then use the shallow: true option
namespaced routes to group related actions
Don't use match to define any routes unless there is need to map multiple request types among [:get, :post, :patch, :put, :delete] to a single action using :via option.
Keep the controllers skinny
all the business logic
should naturally reside in the model
Share no more than two instance variables between a controller and a view.
using a template
Prefer render plain: over render text
Prefer corresponding symbols to numeric HTTP status codes
without abbreviations
Keep your models for business logic and data-persistence
only
Group macro-style methods (has_many, validates, etc) in the beginning of
the class definition
Prefer has_many :through to has_and_belongs_to_many
self[:attribute]
self[:attribute] = value
validates
Keep custom validators under app/validators
Consider extracting custom validators to a shared gem
preferable to make a class method instead which serves the
same purpose of the named scope
returns an ActiveRecord::Relation
object
.update_attributes
Override the to_param method of the model
Use the friendly_id gem. It allows creation of human-readable URLs by
using some descriptive attribute of the model instead of its id
find_each to iterate over a collection of AR objects
.find_each
.find_each
Looping through a
collection of records from the database (using the all method, for example)
is very inefficient since it will try to instantiate all the objects at once
always call
before_destroy callbacks that perform validation with prepend: true
Define the dependent option to the has_many and has_one associations
always use the exception raising bang! method or handle the method return value.
When persisting AR objects
Avoid string interpolation in
queries
param will be properly escaped
Consider using named placeholders instead of positional placeholders
use of find over where
when you need to retrieve a single record by id
use of find_by over where and find_by_attribute
use of where.not over SQL
use
heredocs with squish
Keep the schema.rb (or structure.sql) under version control.
Use rake db:schema:load instead of rake db:migrate to initialize an empty
database
Enforce default values in the migrations themselves instead of in the
application layer
change_column_default
imposing data integrity from
the Rails app is impossible
use the change method instead of up and down methods.
constructive migrations
use models in migrations, make sure you define them
so that you don't end up with broken migrations in the future
Don't use non-reversible migration commands in the change method.
In this case, block will be used by create_table in rollback
Never call the model layer directly from a view
Never make complex formatting in the views, export the formatting to a method
in the view helper or the model.
When the labels of an ActiveRecord model need to be translated, use the
activerecord scope
Separate the texts used in the views from translations of ActiveRecord
attributes
Place the locale files for the models in a folder locales/models
the
texts used in the views in folder locales/views
Use the dot-separated keys in the controllers and models
Reserve app/assets for custom stylesheets, javascripts, or images
Third party code such as jQuery or
bootstrap should be placed in
vendor/assets
Provide both HTML and plain-text view templates
config.action_mailer.raise_delivery_errors = true
Use a local SMTP server like
Mailcatcher in the development
environment
Provide default settings for the host name
The _url methods include the host name and the _path
methods don't
_url
Format the from and to addresses properly
default from:
sending html emails all styles should be inline
Sending emails while generating page response should be avoided. It causes
delays in loading of the page and request can timeout if multiple email are
sent.
.start_with?
.end_with?
&.
Config your timezone accordingly in application.rb
config.active_record.default_timezone = :local
it can be only :utc or :local
Don't use Time.parse
Time.zone.parse
Don't use Time.now
Time.zone.now
Put gems used only for development or testing in the appropriate group in the
Gemfile
Add all OS X specific gems to a darwin group in the Gemfile, and
all Linux specific gems to a linux group
Do not remove the Gemfile.lock from version control.
我想大概的意思就是:如果是 admin 可以看到全部 post,如果不是只能看到 published = true 的 post
use this class from your controller via the policy_scope method:
PostPolicy::Scope.new(current_user, Post).resolve
policy_scope(@user.posts).each
This
method will raise an exception if authorize has not yet been called.
verify_policy_scoped to your controller. This
will raise an exception in the vein of verify_authorized. However, it tracks
if policy_scope is used instead of authorize
need to
conditionally bypass verification, you can use skip_authorization
skip_policy_scope
Having a mechanism that ensures authorization happens allows developers to
thoroughly test authorization scenarios as units on the policy objects
themselves.
Pundit doesn't do anything you couldn't have easily done
yourself. It's a very small library, it just provides a few neat helpers.
all of the policy and scope classes are just plain Ruby classes
rails g pundit:policy post
define a filter that redirects unauthenticated users to the
login page
fail more gracefully
raise Pundit::NotAuthorizedError, "must be logged in" unless user
having rails handle them as a 403 error and serving a 403 error page.
retrieve a policy for a record outside the controller or
view
define a method in your controller called pundit_user
Pundit strongly encourages you to model your application in such a way that the
only context you need for authorization is a user object and a domain model that
you want to check authorization for.
Pundit does not allow you to pass additional arguments to policies
authorization is dependent
on IP address in addition to the authenticated user
create a special class which wraps up both user and IP and passes it to the policy.
set up a permitted_attributes method in your policy
policy(@post).permitted_attributes
permitted_attributes(@post)
Pundit provides a convenient helper method
permit different attributes based on the current action,
If you have defined an action-specific method on your policy for the current action, the permitted_attributes helper will call it instead of calling permitted_attributes on your controller
If you don't have an instance for the first argument to authorize, then you can pass
the class
restart the Rails server
Given there is a policy without a corresponding model / ruby class,
you can retrieve it by passing a symbol
after_action :verify_authorized
It is not some kind of
failsafe mechanism or authorization mechanism.
Pundit will work just fine without
using verify_authorized and verify_policy_scoped
can overwrite the default label by passing it to the input method
configure the html
of any of them
disable labels, hints or error
add a hint,
an error, or even a placeholder
add an inline label
pass any html attribute straight to the input, by using the :input_html
option
use the :defaults option in simple_form_fo
Simple Form generates a wrapper div around your label and input by default, you can pass
any html attribute to that wrapper as well using the :wrapper_html option,
By default all inputs are required
the required property of any input can be overwritten
Simple Form will look at the column type in the database and use an
appropriate input for the column
lets you overwrite the default input type it creates
can also render boolean
attributes using as: :select to show a dropdown.
give the :disabled option to Simple Form, and it'll automatically mark
the wrapper as disabled with a CSS class
Simple Form accepts same options as their corresponding input type helper in Rails
Any extra option passed to these methods will be rendered as html option.
use label, hint, input_field, error and full_error helpers
to strip away all the div wrappers around the <input> field
is to use f.input_field
changing boolean_style from default value :nested to :inline
overriding the :collection option
Collections can be arrays or ranges, and when a :collection is given the :select input will be
rendered by default
Other types of collection
are :radio_buttons and :check_boxes
label_method
value_method
Both of these options also accept
lambda/procs
define a to_label method on your model as Simple Form will search for
and use :to_label as a :label_method first if it is found
create grouped collection selects, that will use the html optgroup tags
Grouped collection inputs accept the same :label_method and :value_method options
group_method
group_label_method
configured with a default value to be used on the site through the
SimpleForm.country_priority and SimpleForm.time_zone_priority helpers.
association
association
render a :select input for choosing the :company, and another
:select input with :multiple option for the :roles
all options available to :select,
:radio_buttons and :check_boxes are also available to association
declare different labels and values
the association helper is currently only tested with Active Record
f.input
f.select
create a <button> element
simple_fields_for
Creates a collection of radio inputs with labels associated
Creates a collection of checkboxes with labels associated
collection_radio_buttons
collection_check_boxes
associations in your model
Role.all
the html element you will get for each attribute
according to its database definition
redefine existing Simple Form inputs by creating a new class with the same name
Simple Form uses all power of I18n API to lookup labels, hints, prompts and placeholders
specify defaults for all
models under the 'defaults' key
Simple Form will always look for a default attribute translation under the "defaults" key if no
specific is found inside the model key
Simple Form will fallback to default human_attribute_name from Rails when no other
translation is found for labels.
Simple Form will only do the lookup for options if you give a collection
composed of symbols only.
"Add %{model}"
translations for labels, hints and placeholders for a namespaced model, e.g.
Admin::User, should be placed under admin_user, not under admin/user
This difference exists because Simple Form relies on object_name provided by Rails'
FormBuilder to determine the translation path for a given object instead of i18n_key from the
object itself.
configure how your components will be rendered using the wrappers API
optional
unless_blank
By default, Simple Form will generate input field types and attributes that are supported in HTML5
The HTML5
extensions include the new field types such as email, number, search, url, tel, and the new
attributes such as required, autofocus, maxlength, min, max, step.
If you want to have all other HTML 5 features, such as the new field types, you can disable only
the browser validation
add novalidate to a specific form by setting the option on the form itself