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...

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...

...security issues in web application, often known as "OWASP Top 10": https://owasp.org/www-project-top-ten/ Rails security Read the following sections from the Rails security guide. For each section you should...

...understand the security issue and what tools Rails gives you to address it. Cross-Site Request Forgery (CSRF) SQL Injection Cross-Site Scripting (XSS) Content Security Policy Also A reasonable...

...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...

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...

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...

Resources Rails Guide: Internationalization API Guide to localizing a Rails application Locale-aware helpers in ActionView::Helpers::NumberHelper Accept-Language HTTP header. Can be parsed with a gem like...

Standard Rails translations The default strings used by Rails can be found in the rails-i18n repository. When we start a new project we often copy the German/English locale...

Rails version Within before_* Within after_* Cancel later callbacks Rails 1-4 return false return false Cancel later callbacks Rails 5+ throw :abort throw :abort Rollback the transaction

raise ActiveRecord::Rollback Rollback the transaction Rails 5+ throw :abort raise ActiveRecord::Rollback Take care that your callbacks don't accidentally return false, since that cancels the chain...

...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...

...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...

...of form.fields_for. You forgot to use accepts_nested_attributes in the containing model. Rails won't complain, but nothing will work. In particular, nested_form.object will be nil.

You are not setting the inverse_of for a has_many through association. Rails will then not be able to process a collection assignment, since it can't find...

makandra Curriculum

...Nested example groups before(:each) after(:each) let subject RSpec.configure, config.before, config.after Resources Everyday Rails Testing with RSpec (in our library), chapter 8 (Keeping Specs DRY) Note: Please refer to...

...render_template() matcher that helps with test above. To get this matcher, add a gem rails-controller-testing. Tip If you place your spec file in spec/requests you don't...

...model validation that restricts its length. There are two motivations for this: In modern Rails, database types :string and :text no longer have a relevant size limit. Without a validation...

...malicious user can quickly exhaust the hard drive of your database server. In legacy Rails (or database schemas migrated from legacy Rails), database types :string and :text had a database...

...comparison can often be seen with simple string comparison like so. # ❌ Not recommended if Rails.version > '6.1.7.8' || RUBY_VERSION > '3.1.4' raise Error, 'please check if the monkey patch below is still...

...comparison above works by coincidence. But chances are that you are not: For example, Rails version 6.1.10.8 would not raise an error in the code block above, because in an...

...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...

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

makandracards.com

...config/initializers/searchkick.rb (or wherever you have configured your Searchkick settings) add: SEARCHKICK_CLIENT_TYPE = case Rails.env when 'production', 'staging', 'development', 'test' :elasticsearch else :opensearch end Searchkick.client_type = ENV.fetch('SEARCHKICK_CLIENT_TYPE...

...SEARCHKICK_CLIENT_TYPE).to_sym ENV['OPENSEARCH_URL'] ||= case Rails.env when 'production' OPENSEARCH_PRODUCTION_SERVER when 'staging' OPENSEARCH_STAGING_SERVER else 'http://opensearch:9200' # docker container name end

...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...

makandra Curriculum

...the behavior, not the implementation" means. Resources Chapter "The value of tests" from Growing Rails Applications in Practice (in our library) Everyday Rails Testing with RSpec (in our library)

...of today, the Rails 7 version of this book is not fully complete. Until then, we have to work with two versions. Concentrate on chapters: 1 (Introduction), 2 (Setting up...

makandra dev
github.com

...All you need is a pretty print-stylesheet. How to use it from your Rails application You can have PDFKit render a website by simply calling PDFKit.new('http://google.com').to...

...separately before calling to_file. Alternatively you can use PDFKit::Middleware and all your Rails routes automagically respond to the .pdf format. This is awesome to get started fast, but...

Recent rails security updates have shown that people make incorrect assumptions about the possible contents of the params hash. Just don't make any! Treat it as what it is...

.../pages/edit?foo --> params == {:foo => nil} /pages/edit?foo[] --> params == {:foo => [nil]} # at least in older rails 3 and in rails 2.x Be especially wary about stuff like User.find_by_password...