Listing posts
Displaying posts 1 - 5 of 338 in total2024-12-05
TODO
Rails 8
1 2 3 4 5 6 7 | # importmap + dartsass, NO hotwire rails new myapp-sass \ --asset-pipeline=propshaft --css=sass \ --skip-action-mailbox --skip-action-text \ --skip-hotwire --skip-jbuilder --skip-test --skip-system-test \ --skip-bootsnap --skip-brakeman --skip-ci --skip-dev-gems \ --devcontainer |
- Rails.error.unexpected: report the given error when in production, or raise it when in development (for conditions not supposed to happen)
- ActiveRecord: rollback a DB transaction with
raise ActiveRecord::Rollback
- ActiveRecord: stop callbacks chain (eg. validation) with
throw :abort
- YJIT enable by default (must be compiled in ruby)
- Controller.rate_limit
- .devcontainer folder when creating a new app.
- default erb PWA files (manifest, service-worker) in app/views/pwa
- GitHub CI files for Dependabot, Brakeman, RuboCop, and running tests by default (--skip-ci)
- Brakeman by default for static analysis of security vulnerabilities (--skip-brakeman option)
- ActiveRecord::Base.with_connection
- allow_browser
News { ActiveRecord | ActionView | ActiveJob | ActionCable | Frontend | Email | ActiveStorage | Security | Core | Devel | Tools&Gems | Testing | Info }
Altro { Upgrade Exp. | References | Tools | Bench. | Books }
New in rails (till 2019-07-06)
⇑ ActiveRecord
ActiveRecord::Relation#pick
=>.limit(1).pluck(*column_names).first
- Model errors as objects @ Rails >= 6.1
- ActiveRecord
store
wrapper aroundserialize
to easily manage a hash value with attribute/keys methods accessors -- api, PR for dirty methods Model.optimizer_hints
PR andModel.annotate
PR- leaverage DB unique constraints:
- ActiveRecord's
reselect
,rewhere
,reorder
- ActiveRecord enum attribute (int value by name) -- api
Item.where(price: 10..)
-- endless ranges in where conditionsActiveRecord::Base.verbose_query_logs = true
: show the query source code line number- multi-db support: suggestions, rake tasks per db, replica option/ro db
- migrations path: PR1, PR2 -- define
migrations_paths
indatabase.yml
- eileen slides
connects_to
,connected_to
switch DB connection PR;connected_to?
check role and connectionrails db:schema:cache:dump
,rails db:schema:cache:clear
-- PR- fix query cache for multiple connections PR
Model.while_blocking_writes{}
blocks/deny DB writes
- migrations path: PR1, PR2 -- define
- Change SQLite 3 boolean serialization from t/f to use 1/0 => migrate old data in DB
Model#delegate_missing_to
-- PR- belongs_to new :default option -- es:
belongs_to :person, default: -> { Person.current }
- ActiveRecord
changes
in callbacks: PR and reference table find_each{|r| ... }
shortcut tofind_in_batches{|b| b.each{|r| ... } }
- also supports
limit
:Post.limit(10_000).find_each{|p| ... }
- also supports
- DB comments
db:migrate
creates development and test databases- migrations: sql expr as default value, es:
t.datetime :published_at, default: -> { 'NOW()' }
- models derive from
ApplicationRecord
instead ofActiveRecord::Base
- ActiveRecord
OR
support, es:Post.where('id = 1').or(Post.where('id = 2'))
- after commit shortcuts:
- ActiveRecord
Model.left_outer_joins
support - foreign keys now supported in create_table DSL
- Active Record ignored_columns -- no accessor methods and no show in queries
- multi context validations -- es:
record.valid?(:ctx_name)
People.in_batches(of: 100){|rel| rel.where... }
-- vedi ActiveRecord::Relation#in_batches- ActiveRecord.suppress -- silently disable record save in block (es:
Model.suppress{...}
) - Attributes API: define attr with a
Proc
, see commit (no moreserialize
misuse) - DB connection pool explained here -- sqlite has no pool
- Set database poolsize via
RAILS_MAX_THREADS
env ActiveRecord::Base.connection_pool.stat
-- status info hash
- Set database poolsize via
find_in_batches
got anend_at
optionactive_record.warn_on_records_fetched_greater_than
-- info
⇑ ActionView
- ActionText: rich text editor integrated with ActiveRecord and ActiveStorage (images/attachments)!! -- guide, intro
- ActionView helper
current_page?
form_with
=form_for
+form_tag
: article, PR1, PR2- new tag helpers -- es:
tag.div(...)
- better controller's
helpers
proxy to use user defined helpers ActionController::Parameters#dig
come per Hash#dig- ActionDispatch
Rails.application.reloader.wrap{}
callback - Per-form CSRF tokens --
config.per_form_csrf_tokens_enabled = false/true
protect_from_forgery
doen't run first anymore, it is simply queued as the other callbacks, use optionprepend: true
to set it as the first callback- NB:
request_forgery_protection
initializer removed from Rails--api
because usually not needed
- NB:
- controller/model's strong parameters
- controller actions default to head :ok if no template exists
- helpers
div_for
andcontent_tag_for
will be gone in Rails 5 => recordtaghelper gem - introduced the
#{partial_name}_iteration
local variable in partials rendered with a collection - live streaming for persistent connections
- caching/faster rendering:
- template dependencies with wildcard support
- strong ETag --
Response#strong_etag=, weak_etag=, fresh_when, stale?
- views cache control -- es:
fresh_when
- declarative etags
⇑ ActiveJob / background jobs
- ActiveJob -- interface for existing queuing systems
- vedi anche: ActionMailer#deliver_later, GlobalID
retry_job
,retry_on
anddiscard_on
catch multiple exceptions- ActiveJob priority support
config.active_job.queue_adapter = :async
-- run jobs in threads a la sucker_punchqueue_name_prefix
-- PR
⇑ ActionCable / websockets
- ActionCable channel_prefix in your cable.yml
- ActionCable -- websockets: live features, chat, notifications | via redis or postgres
- see
ActionController::Renderer
to render views, and usepuma
as a separate process in production
- see
⇑ Frontend
- webpack integration: PR1, PR2 (make default), hp
- yarn javascript package manager used by default -- PR1, PR2, folders
- removed jQuery; vanilla UJS -- guide, jquery-rails, jquery-ujs
- turbolinks:
- turbolinks 5 and 📺 railsconf video
- moved to a separate repo
data-turbolinks-track="true"
moved todata-turbolinks-track="reload"
- Sprockets gzip files
- Sprockets 4 upgrade -- source maps, manifest.js, ES6 support
ActionMailbox
to process incoming emails -- guide- Action Mailer Preprocessing -- eg:
InvitationMailer.with(invitee: person).account_invitation.deliver_later
, see also - email previews
- ActionMailer
rescue_from
come nel controller
⇑ ActiveStorage / upload to cloud -- guide
- ActiveStorage/ActiveJob Mirror direct uploads
- include blob via
Model.with_attached_columnname
-- avoids N+1 query - video/pdf preview
- custom previewers
config.active_storage.routes_prefix = '/files'
custom route prefix
⇑ Security & Paranoia
- MessageEncryptor -- enc/dec strings
- logger/inspect's per model attributes filter -- es:
Model.filter_attributes = [:iban, :cf]
config.action_dispatch.use_cookies_with_metadata = true
-- Add Purpose/Name Metadata to Cookies to enhance security- ActiveRecord.
has_secure_password
: you can specify the attribute name - app-wide
config.force_ssl
deprecatesActionController#force_ssl
- new default headers
X-Download-Options: noopen
andX-Permitted-Cross-Domain-Policies: none
- Content-Security-Policy header DSL, moz ref -- disabled by default in 5.2
- credentials storage PR, guide --
rails credentials:edit
- multi env support:
config/credentials/production.yml.enc
takes precedence overconfig/credentials.yml.enc
, userails credentials:edit --environment staging
to edit specific file secrets PR, guide -- eg:rails secrets:edit
,rails secrets:show
- multi env support:
- secure cookies server side enforced expire time -- es:
cookies.signed[:user_name] = { value: "bob", expires: 2.hours }
- SSL exclude option:
config.ssl_options = { redirect: { exclude: -> request { request.path !~ /healthcheck/ } } }
- Active Support's way to write to a file atomically (thread safe) with
File.atomic_write
⇑ Core/config changes
- new Zeitwerk library loader: blog post, HP
- HTTP early hints/preloading
preload_link_tag
helper: preload + http2 early hints- HTTP2 early hints, PR
- bootsnap installed by default -- TODO: crontab for periodic clean of tmp/cache
- routes: Custom url helpers and polymorphic mapping
- monkey patching is the past:
- use ruby refinements instead of monkey patching
- Deprecate
alias_method_chain
in favor ofModule#prepend
-- howto
- rails API mode: hp
rake xxx:yyy
tasks proxied byrails xxx:yyy
- config
serve_static_files
moved topublic_file_server.enabled
⇑ Development
rails console --sandbox
don't write changes to DB -- PR+cfg- byebug > 8.2.1 is faster
- faster dev reload: set in Gemfile
group :development{gem 'listen', '~> 3.0.4'}
⇑ Tools / External gems
- Router Visualizer: PR, sample -- install graphviz
dot
command, runRails.application.routes.router.visualizer
and save the string to an html file - ActiveRecord XML serialization moved in a gem
- Rails-observers -- separa le callbacks dai models/controllers
- ActiveResource -- consume json via rest
⇑ Testing
- Capybara Integration with Rails (AKA System Tests) -- with selenium and chrome, guide, parallel tests
⇑ Info / Minor changes / Good to know
Array#extract!
-- removes and returns the elements for which the block returns a true value (come select ma modifica la variabile)- execjs: mini_racer replaces therubyracer
rails notes
custom tags -- PRrails notes
task -- shows search code for FIXME/OPTIMIZE/TODO- 📺 Rails 5 video tour by DHH on youtube
rails new
adds a defaultconfig/puma.rb
- String#parameterize per creare id ai titoli dei blog posts
- Array#inquiry.any?(:xxx) -- finds symbols and strings matching xxx
- locale yaml files auto-reloaded in development
- date and time:
DateTime.now.prev_occurring(:monday)
-- PR- Date/Time
#on_weekend?
and#on_weekday?
:D - Time vs DateTime -- commit
- Enumerable#pluck
⇑ Upgrade experiences -- google search
⇑ References
- what's new: https://medium.com/rubyinside/whats-coming-to-rails-6-0-8ec79eea66da
- https://bogdanvlviv.com/posts/ruby/rails/what-is-new-in-rails-6_0.html
- -------------
- https://weblog.rubyonrails.org
- https://guides.rubyonrails.org/upgrading_ruby_on_rails.html
- https://edgeguides.rubyonrails.org/6_0_release_notes.html
- https://guides.rubyonrails.org/5_2_release_notes.html
- https://guides.rubyonrails.org/5_1_release_notes.html
- https://guides.rubyonrails.org/5_0_release_notes.html
- https://guides.rubyonrails.org/4_2_release_notes.html
- https://guides.rubyonrails.org
⇑ Tools
- scaling ruby apps
- 📺 DHH youtube videos on writing sw well
- MiniMagick
- ruby's set: a collection of unordered values with no duplicates
obj.method(:method_name).source_location
=> mostra dov'e' definito il metodo<<~TAG ... TAG
al poso di<<-TAG...TAG
rimuove gli spazi di indentazione!- thor -- build powerful command-line interfaces
⇑ Benchmark howto
1 2 3 4 5 6 7 8 9 | require 'benchmark' a = [:a, :b] b = :b n = 10000000 Benchmark.bm do |x| x.report { n.times do !(Array(a) & Array(b)).empty? end } x.report { n.times do Array(a).include?(b) end } end |
1 2 3 4 5 6 7 8 | require 'benchmark/ips' # instructions per second require 'uri' uri = 'http://example.com/foos_json?foo=heyo' Benchmark.ips do |x| x.report('URI.parse') { URI.parse(uri) } end |
vedi esempi di barnchmark in Hash#deep_merge PR
⇑ Books
- rails6 (beta)
- rails5 test
~~~ * ~~~
2024-11-25
Note: YJIT is only available on arm64 and aarch64.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | apt install rustc # needed by YJIT apt install libjemalloc-dev # needed by jemalloc # install rvm install ruby-3.3.0 -C --with-jemalloc --enable-yjit # jemalloc test 1 MALLOC_CONF=stats_print:true rvm 3.3.0 do ruby -e "exit" # jemalloc test 2 ldd `which ruby` | grep jemalloc # => libjemalloc.so.2 => /lib/aarch64-linux-gnu/libjemalloc.so.2 # YJIT test ruby --yjit -v # => ruby 3.3.0 (2023-12-25 revision 5124f9ac75) +YJIT [aarch64-linux] # YJIT lazy loading: ruby --yjit --yjit-disable -e "... ; RubyVM::YJIT.enable ; ..." |
It's also possibile to apply jemalloc to a vanilla ruby:
1 2 | # enable and test LD_PRELOAD="libjemalloc.so.2" MALLOC_CONF=stats_print:true rvm 3.3.0 do ruby -e "exit" |
Source: jemalloc @ stackoverflow.com, YJIT docs and RVM howto
~~~ * ~~~
2024-11-18
Firefox user interface
From mozilla forum:
- in
about:config
settoolkit.legacyUserProfileCustomizations.stylesheets = true
- clone & install custom CSS from https://github.com/aris-t2/customcssforfx
- uncomment
@import "./css/tabs/tabs_below_navigation_toolbar_fx89.css";
- cd firefox_profile && rm -rf chrome && ln -sf /path/to/repo/current
My about:config settings
browser.download.alwaysOpenPanel = false
-- fix naggin download panel since FF 98browser.tabs.loadDivertedInBackground = true
@security.dialog_enable_delay = 100
@browser.tabs.hoverPreview.enabled = false
@browser.tabs.hoverPreview.showThumbnails = false
(Settings>General>Tabs) @-
- Add new string value
general.useragent.override
- Enter your preferred UA
- Check it on https://www.whatsmyua.info/
This is especially useful if you are on an ARM device (like raspberry pi) and google keeps giving you its mobile version, for example:
1 2
Mozilla/5.0 (X11; Linux armv7l; rv:60.0) Gecko/20100101 Firefox/60.0 # before Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0 # after
- Add new string value
Add-ons
- auto reload tab
- awesome screenshot
- DeepL Translate -- store
- keepa amazon tracker
- pretty xml
- user agent switcher
- video download helper -- hp
- tampermonkey
- save page we
old:
- flash video downloader
- foxy proxy
- page translate
- unicode emoji
- simple tab renamer (attached)
Source: userChrome.org, CustomCSSforFx
~~~ * ~~~
2024-11-13
Resolutions
- Sage: 1440x1920
- Glo: 758x1024
Developer mode / hidden settings
- Type
devmodeon
in the searchbar, search and return to home screen - New menu entry apperars: Settings > Device Information > Developer options
- Optional: type
devmodeoff
to disable it
NickelMenu / quick launcher
- Download latest
KoboRoot.tgz
from home page/github - Connect Kobo to your PC
- Put KoboRoot.tgz into
KOBOeReader/.kobo
- Eject your eReader and wait for it to reboot
- Ensure there is a new menu item in the bottom-right main menu entitled NickelMenu
- Connect Kobo to your PC again and create a file
named
KOBOeReader/.adds/nm/config
, and follow the instructions inKOBOeReader/.adds/nm/doc
to configure NickelMenu
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | menu_item :main :Browser (fullscreen) :nickel_browser : menu_item :main :Browser (modal) :nickel_browser :modal # KOreader: prevent Kobo from scanning hidden folders on 4.17+ # https://github.com/koreader/koreader/wiki/Installation-on-Kobo-devices#important-notes # ==> append in ".kobo/Kobo/Kobo eReader.conf": # [FeatureSettings] # ExcludeSyncFolders=(\\.(?!kobo|adobe).+|([^.][^/]*/)+\\..+) menu_item :main :KOReader :cmd_spawn :quiet :exec /mnt/onboard/.adds/koreader/koreader.sh menu_item :main :Plato :cmd_spawn :quiet :/mnt/onboard/.adds/plato/plato.sh menu_item :main :Invert Screen :nickel_orientation :invert menu_item :main :Sudoku :nickel_extras :sudoku #menu_item :main :Solitaire :nickel_extras :solitaire #menu_item :main :WordScramble :nickel_extras :word_scramble #menu_item :main :Dump Syslog :cmd_spawn :logread > /mnt/onboard/.adds/syslog.log menu_item :main :USB connect :nickel_misc :force_usb_connection menu_item :main :IP Address :cmd_output :500:/sbin/ifconfig | /usr/bin/awk '/inet addr/{print substr($2,6)}' menu_item :main :Telnet :cmd_output :500:quiet :/usr/bin/pkill -f "^/usr/bin/tcpsvd -E 0.0.0.0 2023" chain_success:skip:5 chain_failure :cmd_spawn :quiet :/bin/mount -t devpts | /bin/grep -q /dev/pts || { /bin/mkdir -p /dev/pts && /bin/mount -t devpts devpts /dev/pts; } chain_success :cmd_spawn :quiet :exec /usr/bin/tcpsvd -E 0.0.0.0 2023 /usr/sbin/telnetd -i -l /bin/login chain_success :dbg_toast :Started Telnet server on port 2023 chain_failure :dbg_toast :Error starting Telnet server on port 2023 chain_always:skip:-1 chain_success :dbg_toast :Stopped Telnet server on port 2023 menu_item :main :FTP :cmd_spawn :quiet:/usr/bin/pkill -f "^/usr/bin/tcpsvd -E 0.0.0.0 1021" || true && exec /usr/bin/tcpsvd -E 0.0.0.0 1021 /usr/sbin/ftpd -w -t 30 /mnt/onboard chain_success :dbg_toast :Started FTP server on port 1021. menu_item :main :Sleep :power :sleep #menu_item :main :Reboot :power :reboot menu_item :main :Power Off :power :shutdown menu_item :library :Import books :nickel_misc :rescan_books_full menu_item :browser :Quit :nickel_misc :home menu_item :browser :Open modal :nickel_browser :modal menu_item :browser :Invert Screen :nickel_orientation :invert menu_item :selection_search :WebSearch :nickel_browser :modal:https://duckduckgo.com/?q={1|S|%} |
Notes:
- FTP: user = root
, pass = empty
- Telnet: pass = none
KOReader / alternative reader, swiss knife
See the user guide and wiki, then follow install instructions:
- Download the latest release from github
- Connect Kobo to your PC
- unzip -d /path/to/KOBOeReader/.adds/ koreader-kobo-v2023.04.zip
prevent Kobo from scanning hidden folders on 4.17+, append in
.kobo/Kobo/Kobo eReader.conf
:1 2
[FeatureSettings] ExcludeSyncFolders=(\\.(?!kobo|adobe).+|([^.][^/]*/)+\\..+)
add entry in NickelMenu, put in
.adds/nm/config
:1
menu_item :main :KOReader :cmd_spawn :quiet :exec /mnt/onboard/.adds/koreader/koreader.sh
Eject your eReader and enjoy
From the user guide a command to optimize images for the ereader with ImageMagick:
1 2 3 4 5 6 | convert input-image.ext \ -colorspace Lab -filter LanczosSharp -distort Resize 1404x1872 \ -colorspace sRGB -background white -gravity center -extent 1404x1872! \ -grayscale Rec709Luminance -colorspace sRGB \ -dither FloydSteinberg -remap _eink_cmap.gif \ -quality 75 output-image.ext |
_eink_cmap.gif
is also attached to this post.
Plato / alternative reader
See the forum thread and NickelMenu entry:
- Download the latest release from github
- Connect Kobo to your PC
- mkdir /path/to/KOBOeReader/.add/plato
- unzip -d /path/to/KOBOeReader/.adds/plato/ plato-0.9.36.7z
- prevent Kobo from scanning hidden folders on 4.17+, see KOReader instruction above
add entry in NickelMenu, put in
.adds/nm/config
:1
menu_item :main :Plato :cmd_spawn :quiet :/mnt/onboard/.adds/plato/plato.sh
Eject your eReader and enjoy
Misc tools
- kepubify -- EPUB to KEPUB converter written in Go (standalone executable)
QOL settings
enable screenshots by pressing power button (saves a PNG in kobo root dir), append in
.kobo/Kobo/Kobo eReader.conf
:1 2
[FeatureSettings] Screenshots=true
auto accept the
Computer detected
popup when plugged into a computer and enabledevmodeon
:1 2 3
[DeveloperSettings] AutoUsbGadget=true EnableDebugServices=true
random screensaver (sleep/poweroff):
- put images in
.kobo/screensaver
- Settings > Energy saving and privacy > check
Show current read
andShow book covers full screen
- put images in
Bluetooth page turner
- buy a Ring Remote Control
- install https://github.com/tsowell/kobo-btpt
config file
.adds/.btpt/D01 Pro
:1 2
nextPage EV_KEY KEY_NEXTSONG 0 prevPage EV_KEY KEY_PREVIOUSSONG 0
~~~ * ~~~
2024-11-13
Signs that it's time to quit your job
- You're not learning
- You have a terrible boss
- You're experiencing abuse
- Your workplace is a toxic environment
- Your feedback and ideas are not heard
- You dread going to work in the morning
- Your health is being negatively impacted
- Your company seems financially unstable
- You are being asked to do unethical things
- You feel that there is no growth left for you
- Your knowledge and skills are under-utilised
- You have lost interest or passion for your job
- There is a high turnover rate among employees
- You get no feedback about your performance
- Your responsibilities have increased, but the pay hasn't
- You're consistently stressed, negative, or unhappy at work
Signs of a Bad Manager
- Micromanagement: Constantly checking in on employees and not allowing autonomy
- Poor Communication: Fails to provide clear instructions or feedback
- Lack of Empathy: Shows no understanding or concern for employees' personal issues
- Takes Credit for Others' Work: Does not acknowledge team contributions
- Unapproachable: Creates an environment where employees feel they cannot voice concerns
- Inconsistent: Changes decisions frequently and unpredictably
- Lacks Vision: Does not have a clear direction or goals for the team
- Plays Favorites: Gives preferential treatment to certain employees
- Avoids Responsibility: Blames others for their own mistakes
- Resists Change: Unwilling to adapt to new ideas or improvements