Consul: Dynamically access and query powers for a given name, model class or record
Consul 0.6.1+ gives you a way to dynamically access and query powers for a given name, model class or record.
A common use case for this are generic helper methods, e.g. a method to display an "edit" link for any given record
if the user is authorized to change that record:
module CrudHelper
def edit_record_action(record)
if current_power.include_record?(:updatable, record)
link_to 'Edit', [:edit, record]
end
end
end
You can find a full list of available dynamic calls bel...
Understanding race conditions with duplicate unique keys in Rails
validates_uniqueness_of
is not sufficient to ensure the uniqueness of a value. The reason for this is that in production, multiple worker processes can cause race conditions:
- Two concurrent requests try to create a user with the same name (and we want user names to be unique)
- The requests are accepted on the server by two worker processes who will now process them in parallel
- Both requests scan the
users
table and see that the name is available - Both requests pass validation and create a user with the seemingly available name...
Running "bundle update" without arguments might break your application
Calling bundle update
(without arguments) updates all your gems at once. Given that many gems don't care about stable APIs, this might break your application in a million ways.
To stay sane, update your gems using the applicable way below:
Projects in active development
Update the entire bundle regularily (e.g. once a week). This ensures that your libraries are up-to-date while it's easy to spot major version bumps which may break the app.
Projects that have not been updated in a while
- [Update a single gem conservatively](htt...
Geordi: run a capistrano task on all stages
Geordi now has a script that runs capistrano with all known deploy targets (i.e. staging, production...).
Use with
geordi capistrano deploy:migrations
or
geordi capistrano deploy
The abbrevation geordi cap ...
works as well.
Using Apache Benchmark (ab) on sites with authentication
Apache HTTP server benchmarking tool (ab
) is a nice tool to test performance on sites delivered by HTTP. If the site you're about to test is placed behind a login, follow these steps to successfully use ab
on it.
- Open the site to test in the browser of your choice. Do not login yet.
- Use developer tools to show all cookies used by the site. (Chrome: Ctrl+Shift+i, open the 'Resources' tab and click on the site below 'Cookies' on the left. Firefox: Right-click on the site, open 'We...
Git: How to stash with a custom message
If you say git stash
, your stashed changes will be identified with an automatically generated message:
$ git stash
Saved working directory and index state WIP on master: 77af0df Merge branch 'production'
While this is okay to temporarily stash away stuff, you may want a better identifier for your changes so you can find them more easily if you stash often.
Of course, there is a way to do it with git:
$ git stash save doing crazy things
Saved working directory and index state On master: doing crazy things
Note that you n...
Consul 0.5.0 is faster for admins, allows to define multiple powers at once
When calling a scope like current_power.user?(user)
, Consul will no longer trigger a query if the users
power selects all records (SELECT * from users
). This should make such checks much faster for users who can access many records, like admins.
You can now define multiple powers at once:
power :users, :updatable_users, :creatable_users do
...
end
CSS Explain - A tool which calculates CSS selector specificity
Example input:
li.active a:link
Example output (specificity):
| 0 | 2 | 2 |
See also: https://www.codecaptain.io/tools/css-specificity-calculator
randym/axlsx · GitHub
Axlsx is an incredible gem to generate "Office Open XML" spreadsheet files (XLSX). Does not break on large spreadsheets and supports a ton of features like graphs.
API looks mature and existing code is easy to migrate when coming from the spreadsheet
gem.
The documentation of some methods is a bit out of date, but you'll find your way around the gem's code.
No support for reading files, however. :( If you want to open XLSX spreadsheets (for example to confirm your output in tests), you can use [roo
](h...
Understanding database cleaning strategies in tests
TLDR: In tests you need to clean out the database before each example. Use :transaction
where possible. Use :deletion
for Selenium features or when you have a lot of MyISAM tables.
Understanding database cleaning
You want to clean out your test database after each test, so the next test can start from a blank database. To do so you have three options:
- Wrap each test in a transaction which is rolled back when you're done (through
DatabaseCleaner.strategy = :transaction
or `config.use_transactional_fi...
jquery-timing - a jQuery plugin you should know about
jquery-timing is a very useful jquery plugin that helps to remove lots of nested anonymous functions. It's API provides you some methods that help you to write readable and understandable method chains. See yourself:
Example
// before
$('.some').show().children().doThat();
window.setTimeout(function(){
$('some').children().doSomething().hide(function() {
window.setTimeout(function() {
otherStuffToDo();
}, 1000);
});
}, 500);
// after
$('.some').s...
Custom bash autocompletion
The bash offers control over the behavior of autocompletion.
The most primitive example is this (just run it in your bash; if you want it available everywhere, put the complete ...
line into your .bashrc
):
> complete -W "list of all words for an automatic completion" command_to_be_completed
> command_to_be_completed a<TAB>
all an automatic
With complete
you define how the specified command shall be completed. For basic needs, -W
(as in "word list") should be enough, but you may also specify a function, a glob patte...
Performance analysis of MySQL's FULLTEXT indexes and LIKE queries for full text search
When searching for text in a MySQL table, you have two choices:
- The LIKE operator
- FULLTEXT indexes (which currently only work on MyISAM tables, but will one day work on InnoDB tables. The workaround right now is to extract your search text to a separate MyISAM table, so your main table can remain InnoDB.)
I always wondered how those two methods would scale as the number of records incr...
Render Sass stylesheets dynamically
If - for whatever reason - you have to render stylesheets dynamically, the following snippet might be of help. It emulates what "sprockets" would to when precompiling your assets, and give your stylesheets access to all the regular bells and whistles (like asset_path
, proper @import
s etc):
class DynamicStylesheetsController < ApplicationController
def show
logical_path = RELATIVE_PATH_TO_YOUR_TEMPLATE
path = File.join(Rails.root, logical_path)
template = Sass::Rails::SassTemplate.new(path)
environment = ...
Cronjobs: "Craken" is dead, long live "Whenever"
Our old solution for cronjobs, the "craken" plugin, is no longer maintained and does not work on Rails 3.2+.
We will instead use the whenever gem.
"Whenever" works just like "craken", by putting your rake tasks into the server's cron table. Everything seems to work just like we need it.
Installation for new projects
-
Add "whenever" to your
Gemfile
:group :deploy do gem 'whenever', require: false end
-
Add it to your
config/deploy.rb
:
...
Don't name columns like counter_cache columns in Rails pre v4.2.4
< Rails v4.2.4
ActiveRecord has a feature called counter caching where the containing record in a has_many
relationship caches the number of its children. E.g. when you have House has_many :rooms
, Rails can cache the number of rooms in House#rooms_count
.
Mind that when a model has a column that looks to Rails like a counter-cache column, Rails will apply counter-cache logic to your model, even if you're not using counter caches.
E.g. you have a house with 12...
SearchableTrait is now a gem: Dusen
For two years we've been using SearchableTrait
which gives models the ability to process Googlesque queries like this:
Contact.search('a mix of words "and phrases" and qualified:fields')
This trait used to be a huge blob of code without tests and documentation, so I made a gem out of it. Check out https://github.com/makandra/dusen for code, tests, and a huge README.
You should use the Dusen gem and delete SearchableTrait
in all future projects.
Note that the syntax to define query proc...
How to solve Selenium focus issues
Selenium cannot reliably control a browser when its window is not in focus, or when you accidentally interact with the browser frame. This will result in flickering tests, which are "randomly" red and green. In fact, this behavior is not random at all and completely depends on whether or not the browser window had focus at the time.
This card will give you a better understanding of Selenium focus issues, and what you can do to get your test suite stable again.
Preventing accidental interaction with the Selenium window
--------------------...
Ubuntu: Fix missing sound after a version upgrade
If you can now longer hear or record sounds after upgrading Ubuntu, you probably need to re-tell Ubuntu which devices to use for playback/recording.
Fix sound output
- Open the PulseAudio Volume Control (
pavucontrol
). If you don't have that application, install it withsudo apt-get install pavucontrol
. - Start playback of an MP3 so you can see when changes take effect.
- Under "Output devices" use the "Mute" buttons to figure our which output device is the correct one. When you found it, also set it as the fallback dev...
Rails 2: Calling instance_eval on a scope will trigger a database query
In Rails 2, when calling instance_eval
or instance_exec
on a scope, the scope will fetch its records from the database.
This has been fixed in Rails 3+.
Using sets for many-to-many relationships
A technique to vastly reduce the number of join model records that need to be stored in the database.
The technique is only effective when there is a high redundancy in your data, e.g. combinations of the same 20 tags are used to label thousands of books.
The technique is also limited in that your join models cannot have additional logic, such as attributes or callbacks.
Ther has-many-with-set gem is an implementation of this technique.
How to move a window to the next monitor on Xfce, Mate and other X Window Managers
Since I use this a lot in my daily work and there were no scripts working properly for me, I made one myself.
It's actually not bound to Xfce but should work on any window manager (haven't tried it, though).
Installation
-
If you don't yet have
xdotool
, install it:sudo apt-get install xdotool
-
If you don't yet have
wmctrl
, install it:sudo apt-get install wmctrl
-
Store the attached file in some place that's in your
PATH
.
The cool kids use~/bin/
. -
Make it executable: `chmod +x ~/bin/move-to-next-mo...
Rails: When to use :inverse_of in has_many, has_one or belongs_to associations
When you have two models in a has_many
, has_one
or belongs_to
association, the :inverse_of
option in Rails tells ActiveRecord that they're two sides of the same association.
Example with a has_many
/ belongs_to
association:
class Forum < ActiveRecord::Base
has_many :posts, inverse_of: :forum
end
class Post < ActiveRecord::Base
belongs_to :forum, inverse_of: :posts
end
Knowing the other side of the same association Rails can optimize object loading so forum
and forum.posts[0].forum
will reference the same o...
Writing Fast, Memory-Efficient JavaScript
JavaScript engines such as Google’s V8 (Chrome, Node) are specifically designed for the fast execution of large JavaScript applications. As you develop, if you care about memory usage and performance, you should be aware of some of what’s going on in your user’s browser’s JavaScript engine behind the scenes.