Git log
offers useful options for filtering. This card provides a short overview.
Only commits that include a specific string in their commit message
git log --grep="tracker id"
Only commits that introduced changes to a specific file
git log -- foo.rb bar.rb
If you want to know when a specific line of code was added in the project
git log -S"def function_name"
If you want to know which commits have been added between two commits.
git log base_branch..compare_branch
will s...
Rails comes with grouped_collection_select
that appears to be useful, but isn't.
As an alternative, consider the flat_grouped_collection_select
found below. It takes a third argument that extracts the group from each element in the collection:
= form.flat_grouped_collection_select :user_id, users, :department, :id, :full_name
Here is the monkey-patch:
class ActionView::Helpers::FormBuilder
def flat_grouped_collection_selec...
In general, the tracker should always be the definitive source of truth of what needs to be done as part of a project. If you identify a task that needs to be done, you should create a story. If you learn something that contradicts an existing story, change it.
The tracker can contain two types of stories: Developer stories, and non-developer stories.
Non-developer stories should be clearly marked. They usually belong to the PM (or maybe people from the operations team). Those story can take all forms, could just...
capybara_element['attribute_name']
allows accessing an element's attributes in Capybara.
A few examples:
find('#my_element')['class']
# => "first-class second-class"
find('#my_input')['placeholder']
# => "My placeholder value"
find('a#example-link')['href']
# => "http://example.com"
find('#my_element')['missing_attribute']
# => nil
Sometimes you'll find yourself with a set of tasks that require similar code for different models. For example, if you start working at a new application that allows CRUDing pears and apples, each commit might look similar to this:
commit 41e3adef10950b324ae09e308f632bef0dee3f87 (HEAD -> ml/add-apples-12345)
Author: Michael Leimstaedtner <michael.leimstaedtner@acme.com>
Date: Fri Aug 11 09:42:34 2023 +0200
Add Apples as a new fruit
diff --git a/app/models/apple.rb b/app/models/apple.rb
new file mode 100644
index 0000000..a51...
Suppose you want to implement a publish/subscribe pattern in your Frontend application to react to data changes and events. First, you might be looking for an event emitter library.
Today I learned that vanilla JavaScript comes with a native event emitter, which I've been indirectly using forever. There's no need for extra code!
const emitter = new EventTarget()
emitter.addEventListener('YOLO', () => {
console.log('YOLO');
})
// invoke attached event listeners
emitter.dispatchEvent(new Event('YOLO'));
First find the reference for the entry you want through looking at the stash:
$ git stash list
stash@{0}: WIP on feature/foo
stash@{1}: WIP on feature/bar
stash@{2}: WIP on fix/baz
Now you can simply use that reference, but curly braces must be escaped:
git stash pop stash@\{1\}
or quoted:
git stash apply "stash@{1}"
Do not pass times to date attributes. Always convert times to dates when your application uses time zones.
A time-zoned Time
attribute on a Rails record is converted to UTC using to_s(:db)
to be stored, and converted back into the correct time zone when the record is loaded from the database. So when you are not on UTC, time objects will be converted as follows.
>> Time.current
=> Fri, 15 Mar 2013 11:56:03 CET +01:00
>> Time.current.to_s(:db)
=> "2013-03-15 10:56:03" # This is now UTC
That will...
Typhoeus has a different way of representing array params in a get
request than RestClient.
Typhoeus: http://example.com/?foo[0]=1&foo[1]=2&foo[2]=3
RestClient: http://example.com/?foo[]=1&foo[]=2&foo[]=3
Webmock normalizes this url when matching to your stubs, so it is always http://example.com/?foo[]=1&foo[]=2&foo[]=3
. This might lead to green tests, but in fact crashes in real world. Rack::Utils.build_nested_query
might help to build a get re...
When you write your next CarrierWave uploader, consider processing your images with libvips instead of ImageMagick.
There are several upsides to using libvips over ImageMagick:
Using querySelector
or querySelectorAll
in JavaScript, you can easily find descendants of a node that match a given selector.
But what if you want to find only children (i.e. direct descendants) of an element?
Easy: use :scope
. It references the element on which DOM API methods are being called:
element.querySelectorAll(':scope > .your-selector')
Consider this HTML
<body>
<div id="container1">
<div id="container1a">foo</div>
<div id="container1b">bar</div>
<div id="container1c">baz</...
TL;DR Still has caveats.
Code splitting is a feature of JavaScript bundlers that can keep huge libraries out of the main bundle.
Like Webpack esbuild lets you use the await import()
function to load code on demand:
// application.js
const { fun } = await import('library.js')
fun()
However, esbuild's code splitting is disabled by default. The code above would simply [inline](https://en.wiki...
rubocop -a
Caveat: This adds a little time overhead to saving. When you're editing many files at once (e.g. using "Replace All"), this may be inacceptable.
When RubyMine reports Rubocop returning "exit code -1", upgrading Rubocop can be the fix:
gem install rubocop
"The logs" can be accessed with Ctrl + Shift + A > Show log in (Files). This opens your file manager at the IDEA log location; the log file is called "idea.log".
If your operating system supports it, right click into the file manager > Open in Terminal. There run tail -f idea.log
to follow the log.
Talking with APIs makes more fun using Postman. As an alternative you can also use command line tools like cURL.
snap install postman
How does it help me?
We forked trusty memoizer to make two changes:
-1
.We published our fork as a new gem named memoized.
memoized is API-compatible to memoizer, you just need to include Memoized
instead of `M...
In most projects I know, Cucumber test suite speed is not an issue. Of course, running 350 features takes its time, but still each test for itself is reasonably fast. There is nothing you can do to fundamentally speed up such a test (of course, you should be using parallel_tests).
However, in projects that go beyond clicking around in a web GUI and checking results, there might be various measures to speed things up. Katapult tests for example could be sped up more than 4 times by re...
So you have a heading that is just barely wider than the container it should fit into, and it wraps a single word to a new line and it's not really pretty?
Cry no more, for you can use text-wrap: balance
today to fix that. At least in some browsers.
When browsers encounter a text-wrapping element with text-wrap: balance
style, they will try breaking to a new line sooner, if it balances out the width of lines.
Without text-wrap: balance
|
With text-wrap: balance
|
---|---|
![... |
We have a long-standing checklist for merge requests. However, it hardly matches the intricate requirements for design. This checklist fills the gap.
Before starting implementing, look at all designs: are there components similar to yours? Have they already been implemented? Can you build on this prior art when implementing yours?
alias_method
makes a copy of a method. This works fine until the same method is overridden using prepend
. If the prepend
is executed after alias_method
, you'll either see an infinite loop, or loose the prepended functionality.
Your options are:
prepend
happens before alias_method
alias_method
invocation: rewrite to the modern & better prepend
prepend
invocation: rewrite to the legacy alias_method
Splitting up commits makes the process of reviewing often easier, since you can create several merge requests or review every commit one by one.
So when you find out that you have portions of the code that you initially didn't intend to change or when you do some refactoring along the current changes, you can use one of the following processes to split up the changes into several commits in a logical order:
#1 Splitting up the last n commits into m commits
#2 Adding changes to a previous commit
2.1 While adding new changes
2.2 S...
It most cases it's not necessary to add a version constraint next to your packages in the package.json
. Since all versions are saved in a lockfile, everyone running yarn install
will get exactly the same versions. Yarn saves this lockfile as yarn.lock
and npm as package-lock.json
.
There are some exceptions, where you can consider adding a version constrain to the package.json
:
It most cases it's not necessary to add a version constraint next to your gems in the Gemfile
. Since all versions are saved in the Gemfile.lock
, everyone running bundle install
will get exactly the same versions.
There are some exceptions, where you can consider adding a version constrain to the Gemfile
:
Gemfile.lock
into the version control (not recommended)If you expect method calls in RSpec 3, be aware that the argument matchers use very liberal equality rules (more like ===
instead of ==
).
For example:
expect(subject).to receive(:foo).with(MyClass)
subject.foo(MyClass) # satisfies the expectation
subject.foo(MyClass.new) # also satisfies the expectation
expect(subject).to receive(:bar).with(/regex/)
subject.bar(/regex/) # satisfies the expectation
subject.bar('regex') # also satisfies the expectation
This is usually not an issue, except when your method ...