To allow HTTP 304 responses, Rails offers the fresh_when method for controllers. The most common way is to pass an ActiveRecord instance or scope, and fresh_when will set...

The problem It might seem simple enough to just say: updated_at = Rails.cache.fetch('updated_at_of_expensive_scope') fresh_when last_modified: updated_at The example above calls...

...echo the environment setting in our application layout: <%= tag :meta, name: 'feature:polling', content: Rails.configuration.feature_polling %> Now polling is disabled by default for all tests. Our test suite has immediately...

...scenario 'The project list is updated periodically' do # Enable polling for this test allow(Rails.configuration).to receive(:feature_polling).and_return(true) # Go to the projects index and see an...

davidverhasselt.com

Rails 5 / 6 / 7 Method Uses Default Accessor Saves to Database Runs Validations Runs Callbacks Updates updated_at/updated_on Respects Readonly attribute= Yes No n/a n/a n/a n/a attributes= Yes

No No No No Note that update_attributes is no longer available on Rails 7 (it was only an alias to update before anyway). Rails 4 Method

...Further reading Order of the state_machine callback chain and how to abort it. Rails 5 does not halt callback chain if false is returned Legacy Rails versions...

Rails version Within before_* Within after_* Cancel later callbacks Rails 1-4 return false return false Rollback the transaction Rails 1-4 return false raise ActiveRecord::Rollback

makandra dev

...treats cookies with SameSite=None like SameSite=Strict How to set a SameSite cookie Rails (session configuration) In config/initializers/session_store.rb, add the options secure: true, same_site: :strict|:lax. To set...

...none you need Rack 2 (i.e. Rails 5). Rails 6.1 will set SameSite=Lax; on default. Rails Custom cookies are set with cookies[:cookie_name] = 'value' or = { value: 'value', path...

With this command you can initiate an application restart without touching restart.txt. Unlike touching restart.txt, this tool initiates the restart...

Put the line below in the respective env.rb file to make your action controllers raise an ActionController::UnpermittedParameters error when...

...transactions and locking. Examples will be given for the ActiveRecord ORM (from Ruby on Rails), but apply to all technologies. Use transactions to group related changes Use a transaction to...

...than a single database row, you should always use a transaction. Note that in Rails, ActiveRecord::Base#save automatically opens a transaction. Hence changes you make in callbacks, nested attributes...

...the need for manual intervention that might destabilize or even crash the application. As Rails does not set a timeout on database statements by default, the following query will run...

...statement_timeout"=>"10s"}] begin ActiveRecord::Base.connection.execute("SELECT pg_sleep(15)") rescue ActiveRecord::QueryCanceled => e Rails.logger.error("Query was canceled: #{e.message}") end Adjust or disable the timeout for a single transaction:

makandra dev
api.rubyonrails.org

Rails includes a way to see what an e-mail will look like. Integration to RSpec All you need to do is implement a preview-class in spec/mailers/previews/notifier_preview.rb: class NotifierPreview...

end end And adapt the preview load path in your application.rb: config.action_mailer.preview_path = "#{Rails.root}/spec/mailers/previews" # For Rails < 7.1 config.action_mailer.preview_paths << "#{Rails.root}/spec/mailers/previews" # For Rails >= 7.1 Then a preview will...

github.com

...test using Capybara::Session#save_and_open_page and Capybara::Session#save_screenshot. Use Rails' built-in screenshot module If you want to avoid an external gem and use system...

...tests, you can also use Rails' built-in ScreenshotHelper module available for Rails >= 5. Including assets in HTML screenshots for prettier presentation Note Capybara takes two kinds of screenshots: a...

git_source(:github) { |repo| "https://github.com/#{repo}.git" } ruby "2.7.6" gem "rails", "~> 7.0.6" gem "sqlite3", "~> 1.4" gem "puma", "~> 5.0" This blocks automatic updates of rails, sqlite3 and puma...

git_source(:github) { |repo| "https://github.com/#{repo}.git" } ruby "2.7.6" gem "rails" gem "sqlite3" gem "puma" All gems are easily updateable with bundle update Good source "https://rubygems.org...

Rails 3, 4, 5, 6 config/application.rb config/environment.rb before the initialize! call (we don't usually edit this file) The current environment, e.g. environments/production.rb Gems Vendored plugins All initializers in config/initializers...

...initialize! call (we don't usually edit this file) Your own code from app Rails 2 Code in config/preinitializer.rb (if it exists) environment.rb, code above the Rails::Initializer.run block (put...

...an empty exclusion list returns no records at all! See below for better implementations. Rails 4+ Use the .not method to let Rails do the logic # Good User.where.not(id: []).to...

=> SELECT "users".* FROM "users" WHERE "users"."id" NOT IN (1, 2) Rails < 4 Before Rails 4, you needed to work around this yourself: # Good excluded_ids.blank? ? User.all : User.where("id...

postgresql.org

TL;DR PostgreSQL handles Rails 4+ text and string columns the same. Some libraries may still reflect on the column type and e.g. render differently sized text fields. PostgreSQL offers...

...costs. In most situations text or character varying should be used instead. Up to Rails 3, the column type string defaulted to creating a varchar column limited to 255 characters...

...DELETE. Redirect responses to GET and POST will be followed with a GET. The Rails form_for helper will use a workaround to send POST requests with a _method param...

...Fix on the client: Make a POST request with method override The default configuration Rails and Sinatra includes a Rack middleware that lets you control the HTTP method used for...

Debugging performance issues in your Rails app can be a tough challenge. To get more detailed insights consider using the rack-mini-profiler gem. Setup with Unpoly Add the following...

...up.link.config.noFollowSelectors.push('.profiler-results a') document.addEventListener('up:link:follow', () => { if (window.MiniProfiler !== undefined) { window.MiniProfiler.pageTransition() } }) } # config/initializers/rack_mini_profiler.rb if Rails.env.development? Rails.application.config.to_prepare do Rack::MiniProfiler.config.position = 'top-right' # positon widget top-right Rack::MiniProfiler.config.skip_paths = [ # ignore...

I recently stumbled upon the Rails feature composed_of. One of our applications dealt with a lot of addresses and they were implemented as 7 separate columns in the DB...

...enforced that. Because I used a regular class, I had to build it myself. The Rails-native readonly is sadly only available with ActiveRecord, not with ActiveModel. It would have...

...using ActiveStorage's disk service. This means that stored files are served by your Rails application, and every request to a file results in (at least!) one non-trivial log...

...an example of what loading a single in an example application writes to the Rails log. Started GET "/rails/active_storage/blobs/redirect/..." for ::1 at ... Processing by ActiveStorage::Blobs::RedirectController#show as SVG...

...shoulda-matchers gem gives you some RSpec matchers to test the application of standard Rails validations. Under the hood should-matchers uses the same recipe as outlined above (set invalid...

...screen_name is not a palindrome. Since that check is not possible with standard Rails validations, we write a custom validation method like this: class User < ActiveRecord::Base validate :validate...

...can never change them without forcing users to empty their cache. Note By default Rails sends a header Cache-Control: max-age=0, private, must-revalidate with all responses, including...

...cached by browsers. You do need to pay attention if you redirect outside of Rails, e.g. via your web server configuration. Dealing with incorrectly cached redirects The only fix is...

...add support for parallel tests. You can easily do that by setting config.root: config.root = "#{Rails.public_path}/system/#{Rails.env}#{ENV['TEST_ENV_NUMBER']}".freeze For debugging purposes (e.g. trying to hunt...

...separate environment. You you could read from an ENV variable instead of using your Rails.env. Suggested configuration In total, here is a suggested configuration that you can put into config/initializers/carrierwave.rb...

Empty CSPs with send_file If you use send_file from a Rails controller, you can send potentially dangerous files with an inline disposition iff you also send...

...would execute active content): Content-Disposition: attachment If you use send_file from a Rails controller, the default disposition is attachment. You can also set it explicitly: send_file @attachment.path...

...lot more gems than you think. E.g. when you do this: bundle update cucumber-rails ... you might think this will only update cucumber-rails. But it actually updates cucumber-rails...

...breaking API changes. Which is all the time. In the example above updating cucumber-rails will give you Capybara 2.0 (because capybara is a dependency of cucumber-rails), which will...