Accept nested attributes for a record that is not an association
Note: Instead of using the method in this card, you probably want to use ActiveType's nested attributes which is a much more refined way of doing this.
The attached Modularity trait allows you to accept nested attributes for a record that is not an association, e.g.:
class Site < ActiveRecord::Base
def home_page
@home_page ||= Page.find_by_name('home')
end
does 'a...
Rails: Output helpers for migrations
When you're writing migrations that do more than changing tables (like, modify many records) you may want some output. In Rails > 3.1 you have two methods at hand: announce and say_with_time.
In the migration:
class AddUserToken < ActiveRecord::Migration
class User < ActiveRecod::Base; end
def up
add_column :users, :token, :string
announce "now generating tokens"
User.find_in_batches do |users|
say_with_time "For users ##{users.first.id} to ##{users.last.id}" do
users.each do |user|
...
Ruby and Rails: Debugging a Memory Leak
A memory leak is an unintentional, uncontrolled, and unending increase in memory usage. No matter how small, eventually, a leak will cause your process to run out of memory and crash.
If you have learned about a memory leak, looking at the number of Ruby objects by type can help you track it down:
> pp ObjectSpace.count_objects
{:TOTAL=>77855,
:FREE=>4526,
:T_OBJECT=>373,
:T_CLASS=>708,
:T_MODULE=>44,
:T_FLOAT=>4,
:T_STRING=>65685,
:T_REGEXP=>137,
:T_ARRAY=>984,
:T_HASH=>87,
:T_STRUCT=>12,
:T_BIGNUM=>2,
:T_FILE=>3,
:T_D...
Rails: How to find records with empty associations
Imagine these models and associations:
class Deck < ApplicationRecord
has_many :cards
end
class Card < ApplicationRecord
belongs_to :deck, optional: true
end
Now you want to find all Decks without any Card or all Cards without a Deck.
Rails 6.1+
Rails 6.1 introduced a handy method ActiveRecord#missing to find records without given associations.
Deck.where.missing(:cards)
SELECT "decks".*
FROM "dec...
Rails: How to check if a certain validation failed
If validations failed for a record, and you want to find out if a specific validation failed, you can leverage ActiveModel's error objects.
You rarely need this in application code (you usually just want to print error messages), but it can be useful when writing tests.
As an example, consider the following model which uses two validations on the email attribute.
class User < ApplicationRecord
validates :email, presence: true, uniqueness: true
end
Accessing errors
Let's assume we have a blank user:
user = Us...
Rails: Default HTTP status codes when redirecting
When redirecting you should take care to use the right HTTP status code.
From controllers
When redirecting from a controller, the default status code is 302 Found (aka Moved Temporarily):
red...
Rails: Send links in emails with the right protocol
ActionMailer per default uses http as protocol, which enables SSL-stripping. When a logged-in user follows an http link to your application, it sends the cookies along with it. Although the application redirects the user to https and from that point has a secure connection to the user, an attacker may overhear that first unsafe request and hijack your session.
Teach ActionMailer to use the right protocol
If your application is behind SSL, turn on using https application-wide. In your environment file (either global or per environ...
Rails: Comparison of Dates - before? and after?
tl;dr
Since Rails
6+you can usebefore?andafter?to check if a date/time is before or after another date/time.
Example
christmas = Date.parse('24.12.2022')
date_of_buying_a_gift = Date.parse('12.12.2022')
date_of_buying_a_gift.before?(christmas)
# => true
# Now you are well prepared for Christmas!! ;)
date_of_buying_a_gift = Date.parse('26.12.2022')
date_of_buying_a_gift.after?(christmas)
# => true
# Now you are too late for christmas! :(
Hint
If you want to check if a date/time is between to ot...
Rails: Use STI in Migration
tl;dr
You should decouple migrations from models by embedding models into the migration. To use STI in this scenario you have to overwrite
find_sti_classandsti_name.
Tip
When possible, try to avoid STI in migrations by disabling it.
Example
Warning
This is more for the sake of I want to do it but I kno...
Rails: Accessing helper methods from a controller
In Rails 5+ you can access a helper from a controller using the helpers method:
# Inside a controller action
helpers.link_to 'Foo', foo_path
In older Rails versions you can use view_context instead:
# Inside a controller action
view_context.link_to 'Foo', foo_path
Managing vendor libraries with the Rails asset pipeline
The benefit of the Rails asset pipeline is that it compiles your stylesheets and javascripts to a single file, respectively. However, the consequences are startling if you don't understand them. Among others, the raw asset pipeline requires you to have all your asset libraries in the same folder, which quickly becomes confusing as your set of assets grows. To overcome this, we have two different solutions.
Custom solution
We are using a custom workaround to keep library files apart in their own directories. To avoid b...
Reading the Rails session hash from a Rack middleware
To read the Rails session from a Rack middleware, use env['rack.session']. It's an ActionDispatch::Request::Session object.
class MyMiddlware
def initialize(app)
@app = app
end
def call(env)
status, headers, body = @app.call(env)
session = env['rack.session']
Rails.logger.info("Value of session['foo'] is: " + session['foo'].inspect)
[status, headers, body]
end
end
You may not be able to write to the session this way (I haven't tested this).
Yarn: if integrity check won't let you start rails console
I ran into a situation in which I received the yarn integrity check warning when starting the rails console even though everything was up to date and correct versions in use.
TLDR: run spring stop
I tried starting the rails console without switching to the correct node version first and received the yarn integrity warning.
warning Integrity check: System parameters don't match
error Integrity check failed ...
How to fix: irb / rails console randomly crashing
If your irb or rails console keeps randomly crashing and you can't figure out why then you can try to disable multi-line autocomplete.
Rails: Kill spring with fire
To ensure Spring is not running:
bin/spring stop
pkill -f spring
To prevent Spring from starting again:
export DISABLE_SPRING=1
Rails 4 introduced collection_check_boxes
Starting from Rails 4.0, you can use a special form options helper called #collection_check_boxes. It behaves similar to #collection_select, but instead of a single select field it renders a checkbox and a label for each item in the collection.
= form_for @post do |form|
= form.collection_check_boxes :author_ids, Author.all, :id, :name_with_initial
How generated form params look like
---------------------------------...
A short overview of common design patterns implemented within Rails
The linked content includes a few design patterns implemented with Ruby on Rails.
What is the card indented to achieve?
- You can use the pattern names for code reviews, so all parties know with only a few words which change is requested. Example: "Please use a form object here"
- You can learn about new code patterns
- You should read the sections "Advantages of using design patterns" and "Disadvantages of using design patterns in a wrong way", since design patterns do not replace good code
Included Design Patterns: Service, Value objec...
Plotting graphs in Ruby with Gruff
Geoffrey Grosenbach has created Gruff for easily plotting graphs. It is written in pure Ruby and integrates with Rails applications.
It provides features as automatic sizing of dots and lines (the more values, the thinner the graph's elements), custom or predefined themes, different styles (bar, line, dot and many more) and multiple graphs in one chart.
Installation
In your Gemfile:
gem 'rmagick', :require => false
gem 'gruff'
Then run bundle install (and don't forget to restart your development server.)
Usage
This i...
Vortrag: Elasticsearch Grundlagen und Rails-Integration mit searchkick
Was ist Elastic?
- Suchmaschine, basierend auf Apache Lucene
- größtenteils Open-Source
- einige kommerzielle Features ("Elastic Stack", früher "X-Pack")
- Zugriffsrechte (bis vor kurzen)
- Monitoring
- Reporting
- Graph-Unterstützung
- Machine Learning
- REST-Api (JSON über HTTP)
Grundlagen
Elastic antwortet per Default auf Port 9200
http GET :9200
{
"name": "ntK2ZrY",
"cluster_name": "elasticsearch",
"cluster_uuid": "Bbc-ix5bQZij5vfFU29-Cw",
"version": {
"number": "6.7.1",
"build_flavor": "...
Save ActiveRecord models without callbacks or validations (in Rails 2 and Rails 3)
Rails 2
You can use
record.send(:update_without_callbacks)
or
record.send(:create_without_callbacks)
This can be used as a lightweight alternative to machinist's make or FactoryGirl's create, when you just need objects in the database but don't care about any callbacks or validations. Note that create_without_callbacks does not return the object, so you might want to do
record = Record.new.tap(&:create_without_callbacks)
Rails 3
Rails 3 no longer comes with update_without_callbacks or `crea...
Rails: Parsing a time in a desired timezone
Sometimes you want to have a time in a given timezone independent from you Rails timezone settings / system timezone. I usually have this use case in tests.
Example
Time.parse('2020-08-09 00:00') will return different results e.g. 2020-08-09 00:00:00 +0200 depending on the Rails timezone settings / system timezone. But in this example we always want to have the given time in UTC because that's what the API returns.
it 'returns a valid API response', vcr: true do
expect(client.get('/users/1')).to have_attributes(
name: 'So...
Persist Rails or IRB Console Command History After Exit
Create, or edit your ~/.irbrc file to include:
require 'irb/ext/eval_history' # was 'irb/ext/save-history' for versions prior to Ruby 3.3
IRB.conf[:SAVE_HISTORY] = 2000
IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb-history"
Heads up: Rails offers two similar means for text truncation
Rails defines a #truncate helper as well as a method String#truncate.
= truncate("my string", length: 5)
= "my string".truncate(5)
Both are really similar; in fact, the helper invokes the method and improves it with two niceties: support for passing a block (which could e.g. render a "read on" link), and html_safe knowledge.
Prefer the truncate() helper
Warning: truncate() calls html_safe if you're not escaping. FWIW, an HTML string may easily become invalid when truncated, e.g. when a closing tag gets chopped off.
...