2019
How to tell the difference between a default and a provided value for optional arguments in Ruby?
It is sometimes required for the methods with optional arguments to be able to differentiate between its default value and the value passed from the caller. Passing nil
might initially sound like a good idea since it represents “nothingness”. However, it might turn out that nil
is a legit value and there might be cases where it is desirable for the caller to pass nil
. In such a case, we cannot use it as a default value if we want to implement a special logic for the case of not providing that value.
2018
Inheritance and define_method - how to make them work together
Imagine that you are implementing some form object because you are fed up with treating ActiveRecord models as such, and you need some extra flexibility. You start with a straightforward implementation for a base class of a form object where you can just whitelist attributes. That could look like this:
Read on →Rails Quick Tips: Temporarily Disabling Touching with ActiveRecord.no_touching
Touching ActiveRecord models is quite a common thing in most of the Rails applications, especially useful for cache invalidation. By default, it updates updated_at
timestamp with the current time, Here’s a typical example of using touch in a model:
PostgreSQL Quick Tips: Working With Dates Using EXTRACT function
Imagine that you are implementing an e-commerce platform and want to grab all orders from the current year. What would be the simplest way of doing it in Rails? Probably writing a query looking like this:
Read on →2017
The aesthetics of Ruby - Kernel#itself method
Recently, I’ve had quite a popular problem to solve: count the occurences of the given item in a collection. There are few ways to solve this problem - starting from using Enumerable#inject
or Enumerable#each_with_object
with an empty hash as an accumulator value and writing a code looking like this:
Traps on Rails - Overriding boolean methods in models
One very useful feature of ActiveRecord is automatically defining attribute readers and writers for all the columns for given tables. For the ones with boolean type, however, there is one more addition - defining an alias of the method with a question mark. Sometimes it might be useful to override this method and add some extra requirements for a given condition. However, this might not be such a good idea.
Read on →Ember Tips: Testing Outgoing HTTP Requests
Ember.js is a web frontend framework and it’s no surprise that majority of the applications deal with a lot of HTTP requests. But such fact has a lot of implications on the process of development of the Ember apps, especially when it comes to testing. For basic GET
requests which don’t include any query params or don’t deal with pagination it’s quite straight-forward - for those we just want to fetch some data, so we can check if proper objects are present as a side-effect of these requests. What about POST
, PATCH
or DELETE
requests, where we can’t easily test the side effects?
Ruby Memoization: ||= vs. defined? syntax
In the majority of the Rails applications or even Ruby gems you can find a lot of use cases where you need to memoize a result of some computation for performance benefits and to not compute it again if this result has already been computed. Seems like doing the assignment to some instance variable with ||=
operator is the most commonly used solution for this purpose, e.g. @result ||= do_some_heavy_computation
. However, there are some cases where it might not produce the expected outome and you should actually use defined?
operator instead.
Ember Tips: Managing Timeouts And Delays
Timeouts and delays are quite extensively used in many applications when deferring execution of some action via Ember.run.later
or debouncing via Ember.run.debounce
. Having small amounts of tests executing such methods might not be a problem initially, but obviously, as the application grows, this can easily lead to slow test suite which takes minutes to finish due to the waiting for all the timeouts and delays in many places. Let’s try to find the best solution to solve this problem.
Test Driven Ember - Testing Holding a Button
Thanks to the awesome tools in Ember ecosystem such as ember-cli-mirage, ember-qunit or ember-test-helpers writing majority of the tests is pretty straight-forward. Nevertheless, there are quite a few cases where simulating user’s interaction is not that simple. An example of such use case would be holding a button for particular period of time triggering some side effect.
Read on →JavaScript Tips: Redefining userAgent property
Imagine a use case where you are trying to check if a user accessed your app from a mobile device or not. Most likely you will need to use navigator.userAgent property and craft some smart regular expression to test for the presence of particular expression, like (/Mobi/.test(navigator.userAgent)
which seems to be the recommended way to do it. Ok, so we’re almost done with our feature, we just need to add some tests to make sure it works as expected. But there’s a problem - you can’t redefine userAgent
property with just using a setter! Fortunately, there is a way to solve this problem.
2016
Ember Tips: Computed Properties And Arrow Functions? Not A Good Idea
Arrow function expressions were definitely a great addition in ES6 and thanks to tools like babel the new syntax has been quite widely adopted. Besides more concise syntax, an interesting thing about arrow function expressions is that they preserve the context, i.e. they don't define their own this
, which was sometimes annoying and resulted in assigning that
or self
variables to keep the outer context that could be referred inside functions. As great as it sounds, arrow function expressions cannot be used in all cases. One example would be Ember computed properties.
Keeping Data Integrity In Check: Conditional Unique Indexes For Soft Delete
Soft delete is a pretty common feature in most of the applications. It may increase complexity of the queries, nevertheless, not deleting anything might be a right default as the data might prove to be useful in the future: for restoring if a record was removed by mistake, to derive some conclusions based on statistics and plenty of other purposes. It may seem like it's a pretty trivial thing: just adding a column like deleted_at
and filtering out records that have this value present. But what happens when you need to do some proper uniqueness validation on both model layer and database level? Let's take a look what kind of problem can easily be overlooked and how it can be solved with a conditional index.
Little-known but useful Rails features: ActiveRecord.extending
Every now and then I discover some features in Rails that are not that (arguably) commonly used, but there are some use cases when they turn out to be super useful and the best tool for the job. One of them would definitely be a nice addition to ActiveRecord::QueryMethods
- extending
method. Let’s see how it could be used in the Rails apps.
When validation is not enough: PostgreSQL triggers for data integrity
Is validation in your models or form objects enough to ensure integrity of the data? Well, seems like you can't really persist a record when the data is not valid unless you intentionally try to bypass validation using save: false
option when calling save
or using update_column
. What about uniqueness validation?
A classic example would be a unique email
per user. To make sure the email is truly unique we could add a unique index in database - not only would it prevent saving non-unique users when bypassing validation, but also it would raise extra error when 2 concurrent requests would attempt to save user with the same email. However, some validations are more complex that ensuring a value is unique and index won't really help much. Fortunately, PostgreSQL is powerful enough to provide a perfect solution to such problem. Time to meet your new friend: PostgreSQL triggers.
PostgreSQL In Action: Sorting With NULLIF Expression
Ordering with ActiveRecord and PostgreSQL may seem like an obvious and simple thing: in most cases you just specify one or several criteria with direction of ordering like order(name: :asc)
and that's all, maybe in more complex scenarios you would need to use CASE
statement to provide some more customized conditions. But how could we approach sorting with forcing blank values to be the last ones, regardless of the direction of the sort? You might be thinking now about NULLS LAST
statement for this purpose, but that's not going to handle empty string. For this case you need something special: time to meet NULLIF
conditional expression.