postgresql create extension without giving the application superuser rights
If you need a postgresql extension for your database it isn't a good idea to give your applications database user superuser rights (like many people on stackoverflow think)
Just login to the database with a superuser account (e.g. postgres) and create the extension with it.
Example:
# with the default configuration of postgresql you normally can login as `postgres` user
# without a password if you use the systems `postgres` user
$ sudo su -l postgres
$ pgsql
postgres=# \c your_database;
psql (9.3.9, server 9.3.5)
You are now connected...
ActiveRecord: scoped `validates_uniqueness_of` allows one null value per scope
As you most likely know validates_uniqness_of :foreign_id
does not allow nil
values by default.
To allow nil
one has to set the :allow_nil => true
option.
Very unexpected scoping this validation will not raise an error if foreign_id
set to nil
for the first created record of this kind.
validates_uniqueness_of :foreign_id, :scope => :another_column # allows foreign_id to be nil
Without a validation for presence of foreign_id
now unusual records could be created.
How to deal with 'parent id missing' error in nested forms
tl;dr
- Use form models to handle this problem
- Or soften the validation to
validates_presence_of :parent
Usually you would validate presence of parent object id, like in this example:
class Parent < ActiveRecord::Base
has_many :nested, :inverse_of => :parent
accepts_nested_attributes_for :nested
end
class Nested < ActiveRecord::Base
belongs_to :parent
validates_presence_of :parent_id # <-
end
With the parent already persisted creating nesteds still works fine.
But one will encounter a *'parent id missing' er...
How to enable SSL in development with Passenger standalone
Here is how to start your Rails application to accept both HTTP and HTTPS in development.
-
gem install passenger
-
Create a self-signed SSL certificate. Store the generated files in config/passenger-standalone-ssl.
-
Create a Passengerfile.json at the project root with this content (or save the attached file):
{ "ssl": true, "ssl_port": 3001, "ssl_certificate": "config/passenger-standalone-ssl/server.crt",
...
Getting Sidekiq error "delay is defined by Active Record"
Reason: You very likely have a model that has a delay
attribute.
You can configure Sidekiq to remove its delay
method by adding this to your Sidekiq initializer:
Sidekiq.remove_delay!
If you need to keep Sidekiqs delay
features, add Sidekiq.hook_rails!
before the option above. The sidekiq methods will be prefixed with sidekiq_
then.
PostgreSQL: Be careful when creating records with specific ids
In tests, it is sometimes useful to create records with specific ids. On PostgreSQL this can cause problems:
Usually, PostgreSQL uses an "autoincrement" sequences to provide sequential ids for new database rows. However, these sequences will not increment if you insert a record "by hand". This will cause an error:
record = Record.create!
record.id # => 100, next automatic id will be 101
Record.create!(id: record.id + 1) # okay, but next automatic id will still be 101
Record.create! ...
Mocking time in Jasmine specs
The easiest way to freeze or travel through time in a Jasmine spec is to use the built-in jasmine.clock()
.
- After
jasmine.clock().install()
you can use it to controlsetTimeout
andsetInterval
. - Using
jasmine.clock().mockDate()
you can mocknew Date()
(which returns the current time in Javascript)
While you can use SinonJS Fake timers, using the built-in Jasmine clock will save you an extra dependency.
Detecting N+1 queries with Bullet
The Bullet gem is designed to help you increase your application's
performance by reducing the number of queries it makes. It will watch
your queries while you develop your application and notify you when
you should add eager loading (N+1 queries), when you're using eager
loading that isn't necessary and when you should use counter cache.
Rails 4.2 Foreign Key Support
The migration DSL now supports adding and removing foreign keys. They are dumped to schema.rb as well. At this time, only the mysql, mysql2 and postgresql adapters support foreign keys. @rubyonrails
Workings
add_foreign_key(:comments, :users)
adds a database constraint
ALTER TABLE "comments" ADD CONSTRAINT comments_user_id_fk FOREIGN KEY ("user_id") REFERENCES "user" ("id")
Disadvantage
Foreign key constraints double the validatio...
JavaScript events: target vs currentTarget
tl;dr: Use event.currentTarget
unless you are absolutely certain that you need event.target
.
Since it hasn't been written down in this deck before, here it goes:
When working with JavaScript Event
objects, the DOM element that triggered the event is attached to them. [1]
However, there are 2 "opinions" on which element that would be:
- The element that the user interacted with (
event.target
), - or the element that the event listener is bound to (
event.currentTarget
).
Note that both can be, but not...
How to capture changes in after_commit
Your after_commit
callbacks will not know about changes, as Rails discards them when committing.
The linked article shows a clever trick to work around that: It uses an after_save
method that looks at changes
and writes its decision to an instance variable. That instance variable can then be used in the after_commit
method.
Note that while callbacks like after_save
are not affected, there are valid reasons for using only after_commit
, and not after_save
. Enqueueing a Sidekiq job is just one of them.
Rails 5+
You can use ...
24 little known CSS facts
This blew my mind today:
Please make sure to check browser support for CSS features on Can I Use and the Mozilla Development Network before using.
Favorites
-
outline-offset
: specify how far away from the element an outline is rendered -
::first-letter
: matches the first letter insid...
emcien/iso_latte
Sometimes you need to run background jobs that you can't make important guarantees about - they may run out of memory and get killed, or produce segmentation faults, or exit! directly - and you need to be able to clean up after such problems.
IsoLatte is a gem that allows a block of code to be executed in a subprocess. Exceptions get passed back to the parent process through a pipe, and various exit conditions are handled via configurable callbacks.
Protip: Clone large projects multiple times
Large projects usually have large test suites that can run for a long time.
This can be annoying as running tests blocks you from picking up the next story -- but it doesn't have to be that way!
Simply clone your project's repo twice (or even more often).
When your work on a feature branch is done, simply push that branch and check it out on your 2nd copy to run tests there.
You can pick up a new story and work on that on your "main" project directory.
If you do it right, you will even be able to run tests in both your 2nd copy and your m...
FactoryGirl: How to easily create users with first and last name
In most of our applications, users have their first and last name stored in separate columns. However, specifying them separately quickly gets annoying, especially when proxying them from cucumber_factory:
Given there is a user with the first name "Dominik" and the last name "Schöler"
Wouldn't it be nice if you could just say:
Given there is a user with the name "Dominik Schöler"
and have FactoryGirl assign first and last name automatically? The code below achieves that!
##...
How to disable auto-complete on login forms
Disabling auto-complete in login forms is probably a bad idea, since it encourages weak passwords.
If you are still forced to implement this (maybe due to legal or policy requirements), this is how:
Prevent browsers from saving the password in the first place. Disabling autocomplete does not improve security.
How to prevent password saving:
To prevent the browser from saving passwords (and usernames), you need to:
- copy username and password to hidden form fields before submitting the login form
- c...
Faster debugging with RubyMine macros
In my RubyMine I have recorded two macros for debugging and linked them to some keyboard shortcuts. Since I believe everyone could benefit from having those I wanted to share this.
The first one simply inserts
binding.pry
and the second one
.tap { |object| binding.pry }
for when you do not have a reference to the object you want to inspect.
In order to record a macro you simply follow the path Edit > Macros > Start Macro Recording
.
Then you simply type binding.pry
or whatever you want to record and stop recor...
Casting ActiveRecord scopes or instances to ActiveType extended model classes
When working with ActiveType you will often find it useful to cast an ActiveRecord instance to its extended ActiveType::Record
variant.
Starting with active_type 0.4.0 you can use ActiveType.cast
for this:
class User < ActiveRecord::Base
...
end
class SignUp < ActiveType::Record[User]
...
end
user = User.find(1)
sign_up = ActiveType.cast(user, SignUp)
sign_up.is_a?(SignUp) # => true
This is basically like [ActiveRecord#becomes
](http://apidock.com/rails/v4.2.1/ActiveRecord/...
Rails 3 ActiveRecord::Persistence#becomes does not copy changed attributes
Note: ActiveRecord::Base#becomes
has a lot of quirks and inconsistent behavior. You probably want to use ActiveType.cast
instead.
This issue will be encountered when relying on attribute_was
methods of ActiveModel::Dirty
after casting a model which has defaults to a form model, for example.
In my case a record with an assignable_values legacy value beca...
Databases don't order rows unless you tell them so
There is no such thing as a "default order" of rows in database tables.
For instance, when you paginate a result set: When using LIMIT
, it is important to use an ORDER BY
clause that constrains the result rows into a unique order. Otherwise you will get an unpredictable subset of the query's rows. You might be asking for the tenth through twentieth rows, but tenth through twentieth in what ordering? The ordering is unknown, unless you specified ORDER BY
.
In Rails, if you use Record.first
or Record.last
, it will default to orderin...
High Performance Browser Networking: HTTP/2
HTTP/2 will make our applications faster, simpler, and more robust—a rare combination—by allowing us to undo many of the HTTP/1.1 workarounds previously done within our applications and address these concerns within the transport layer itself. Even better, it also opens up a number of entirely new opportunities to optimize our applications and improve performance!
Querying model errors in Rails 4
ActiveModel
supplies an errors object that behaves similar to a Hash. It can be used to add errors to a record, as well as to query the record for registered errors. This object is returned when calling <object>.errors
:
errors = @user.errors # => #<ActiveModel::Errors ...>
Here are some helpful messages of its API:
[<attribute name>]
-
Returns an array of error messages on that attribute. Example:
errors[:name] => ['is missing']
-
add_on_blank(<attribute list>)
(similarlyadd_on_empty
) -
Registers an error ...
sessionStorage: Per-window browser storage
All major browsers (IE8+, FF3.5+, Safari 4+, any Chrome) support sessionStorage
, a JavaScript storage object that
- survives page reloads and browser restores,
- but is different per new tab/window (in contrast to
localStorage
which is shared across all tabs).
MDN says:
The
sessionStorage
object is most useful for hanging on to temporary data that should be saved and restored if the browser is accidentally refreshed
Demo
Example usage:
Show details of TLS/SSL connections of remote hosts
sslscan
is a nice tool to show details about TLS/SSL connections:
~> sslscan some-host-at.makandra.de
Testing SSL server some-host-at.makandra.de on port 443
Supported Server Cipher(s):
Failed SSLv3 256 bits ECDHE-RSA-AES256-GCM-SHA384
Failed SSLv3 256 bits ECDHE-ECDSA-AES256-GCM-SHA384
Failed SSLv3 256 bits ECDHE-RSA-AES256-SHA384
Failed SSLv3 256 bits ECDHE-ECDSA-AES256-SHA384
Rejected SSLv3 256 bits ECDHE-RSA-AES256-SHA
...
Prefered Server Cipher(s):
TLSv1 128 bits ECDHE-RSA-A...