How to use object destructuring with the index over an array?
const names = ['Roy', 'Liz', 'Sofia', 'Clau']
const {
0: zero,
1: one,
2: two,
3: three,
} = names
console.log(zero) // 'Roy'
const names = ['Roy', 'Liz', 'Sofia', 'Clau']
const {
0: zero,
1: one,
2: two,
3: three,
} = names
console.log(zero) // 'Roy'
git rebase -i --root
I read about CSS Grid Layout, and I found the Fr
unit, so I have to try it out.
From w3.org:
Flexible Lengths: the fr unit A flexible length or is a dimension with the fr unit, which represents a fraction of the leftover space in the grid container. Tracks sized with fr units are called flexible tracks as they flex in response to leftover space similar to how flex items with a zero base size fill space in a flex container.
The distribution of leftover space occurs after all non-flexible track sizing functions have reached their maximum. The total size of such rows or columns is subtracted from the available space, yielding the leftover space, which is then divided among the flex-sized rows and columns in proportion to their flex factor.
Each column or row’s share of the leftover space can be computed as the column or row’s * / .
See this example:
CSS:
.grid-container {
max-width: 100%;
margin: 3em auto;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: 50px 200px 50px;
grid-template-areas: "head head2 head3 head4" "main main2 main3 main4" "footer footer footer footer";
}
Result:
grid-template-columns: repeat(4, 1fr);
1fr is for 1 part of the available space, each column take up the same amount of space.
I will update the 3rd column to size up to 4fr
CSS:
.grid-container {
max-width: 100%;
margin: 3em auto;
display: grid;
grid-template-columns: 1fr 1fr 4fr 1fr;
grid-template-rows: 50px 200px 50px;
grid-template-areas: "head head2 head3 head4" "main main2 main3 main4" "footer footer footer footer";
}
Result:
See a live example: CSS Grit: Fr Unit by Victor Velazquez (@vicmaster) on CodePen.
That's all folks!
Learned by Victor Velazquez on Apr 28, 2022about to_not have_content
:
expect(page).to_not have_content("not on page")
it waits (Capybara's default waiting time), then it pass. Don't use it! 🚫
whereas to have_no_content
:
expect(page).to have_no_content("not on page")
Waits (same as with .to_not
) but it passes as soon as "not on page"
disappears from the page; use this one to wait for loading messages to disappear! ✅
If you need to add styles to an element when the page is in dark mode, simply use the data-scheme of the page followed by the class or ID of the element you want to add styles to.
[data-scheme="dark"] .js-subs-text-inputs {
color: #FFFFFF;
}
If you ever encounter a Linux dir in which you cannot write even when you're sure you have write permissions on it, check the ACLs. You may find someone doesn't particularly like you. 😞
-> getfacl /tmp
# file: tmp
# owner: root
# group: root
# flags: --t
user::rwx
group::rwx
other::rwx
user:my_user:--- # this means "screw u and only u"
In Ruby, we can write classes inside modules. We usually do this to have classes namespaced to the module, so we don't risk two different classes having the same name. This is important since Ruby won't complain about re-defining a class, it would just open it and add new methods to it.
We could write classes using their full name, like this:
class Pokemon::Game::SpecialAttack < Pokemon::Game::Attack
# ...
end
or, we could wrap the whole thing using modules, like this:
module Pokemon
module Game
class SpecialAttack < Attack # Ruby looks for SpecialAttack inside Pokemon::Game automatically!
# ...
end
end
end
Both methods work the same, except the one above can only reference Attack
using its whole name. On the other hand, it looks somewhat easier to read than nesting modules inside other modules. Which style do you prefer?
ssh-rsa
is the most common public/private key type, but is widely considered insecure with key lengths lower than 2048 bits. If you created your SSH key using ssh-keygen
with default options a while ago, chances are you're using an unsafe key. Furthermore, support for RSA host keys (keys that identify the server you're trying to connect to) is disabled by default since OpenSSH 8.8 and they may consider disabling the algorithm altogether in the future.
But don't worry! Just create a new key for yourself using the most recommended key type available today: ED25519.
ssh-keygen -t ED25519 -a 100 -C "myemail@email.com"
Just make sure you got OpenSSH 6.5 or greater on both ends. Don't forget to install your new key and remove the old one!
Learned by kevin-perez on Mar 4, 2022TIL about OOUX, this article by Dale Owen sent me into a new internet Rabbit Hole. https://uxdesign.cc/what-is-object-oriented-ux-19e14c435d18 The philosophy of OOUX is to encourage us as UX Designers to think about our core content as objects, and to think about this before considering any procedural actions.
Give it a chance worth the reading.
Learned by aldo-mosqueda on Feb 17, 2022Spread syntax allows an iterable such as an array expression or string to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected, or an object expression to be expanded in places where zero or more key-value pairs (for object literals) are expected. [1]
[1] Source: MDN Web Docs
[...'👨🎤']
(3) ['👨', '', '🎤']0: "👨"1: ""2: "🎤"length: 3[[Prototype]]: Array(0)
[...'🧟']
['🧟']
[...'👩👩👧👧']
(7) ['👩', '', '👩', '', '👧', '', '👧']
Learned from @mgechev at https://twitter.com/mgechev/status/1490920854313648128/photo/1
Useful? not sure
Interesting? Hell yeah!
Learned by Victor Velazquez on Feb 8, 2022I had this error when I tried to install a python version with pyenv
on MacOs big sur.
By running this command it worked for me!
CFLAGS=-I$(brew --prefix openssl)/include -I$(brew --prefix bzip2)/include -I$(brew --prefix readline)/include -I$(xcrun --show-sdk-path)/usr/include LDFLAGS=-L$(brew --prefix openssl)/lib -L$(brew --prefix readline)/lib -L$(brew --prefix zlib)/lib -L$(brew --prefix bzip2)/lib \ pyenv install --patch 3.8.0 < <(curl -sSL https://github.com/python/cpython/commit/8ea6353.patch\?full_index\=1)
Now when I run pyenv versions
I have the python versions
In the Rails Console run next lines:
key = SecureRandom.base64(24) # random 32 bits key in order to encrypt
crypt = ActiveSupport::MessageEncryptor.new(key) # e.g. "PALkim1eXHeyGxFWhf+B4OvEYm6LXLtm"
encrypted_data = crypt.encrypt_and_sign('my favorite beer is La María') # "KgIkPJsn9n3JV4Y...=="
decrypted_data = crypt.decrypt_and_verify(encrypted_data) # decrypted message should concur with the original.
Let's say:
I have mydomain.mx and I want to allow anybody to type in the browser
www.mydomain.mx
# or
mydomain.mx
# or
http://mydomain.mx
# or
http://www.mydomain.mx
And to resolve/redirect
to the secure version of it -> https://mydomain.mx (non www)
It is basically done, following this approach:
Add your domain with two variations inside the settings section within heroku.com
Create those two CNAMEs entries in your DNS providers (I'm using cloudfare.com for free)
Create a redirect rule in your application(this depend on the technology and language you are using), in my case, as I'm using Rails, so it was a matter of adding this to the top of the config/routes.rb
file:
match '(*any)',
to: redirect(subdomain: ''),
via: :all,
constraints: { subdomain: 'www' }
There you go! you are ready to go, here is a live example (Site in construction as of November 26th, 2021)
www.valoralo.mx
http://valoralo.mx
http://www.valoralo.mx
valoralo.mx
All of them will resolve to the same domain:
https://valoralo.mx
The spaceship operator compares two objects (from left to right), returning either -1, 0, or 1.
a <=> b
return -1 if a < b
return 0 if a == b
return 1 if a > b
4 <=> 7 # -1
7 <=> 7 # 0
7 <=> 4 # 1
As you know, in ruby (as in any language) we can get a result in different ways, we could use just the sort
method, of course, but I just wanted to put this in another way:
languages = ['ruby', 'go', 'javascript', 'phyton', 'rust', 'elixir']
languages.sort{|first, second| first <=> second } # ["elixir", "go", "javascript", "phyton", "ruby", "rust"]
languages.sort{|first, second| second <=> first } # ["rust", "ruby", "phyton", "javascript", "go", "elixir"]
Suppose that we have the next array with the numbers 1 to 10
, and we will like to separate them into different groups:
1. One group for the numbers that are less than 5
2. Another group with the number 5
3. The last group with the numbers that are greater than 5
We could get this result by iterating the array and then by putting a couple of if statements in order to group these 3 categories, but with the spaceship operation we could get this result in an easier way:
numbers = Array(1..10)
target = 5
numbers.group_by{ |number| number <=> target } # {-1=>[1, 2, 3, 4], 0=>[5], 1=>[6, 7, 8, 9, 10]}
Imagine that we have the next object:
const names = [
{ name: 'Sam', lastName: 'Belmor'},
{ name: 'Yasser', lastName: 'Velasco' },
{ name: 'Ayrton', lastName: 'Morales' }
]
If we wanna sort those values alpabethically by name we could do this:
names.sort((a, b) => (a.name > b.name) ? 1 : -1)
We'll have this result:
[
{ name: 'Ayrton', lastName: 'Morales' },
{ name: 'Sam', lastName: 'Belmor' },
{ name: 'Yasser', lastName: 'Velasco' }
]
If return 1, the function communicates to sort() that the object b takes precedence in sorting over the object a. Returning -1 would do the opposite.
Learned by samantha-bello on Nov 16, 2021Sometimes we want to create a parent class that will be shared for children classes, nevertheless, in some of the children classes we need additional arguments that will be only specific for that class and we don't need them in the parent class, to avoid adding additional arguments that won't be relevant to the parent class, we can do the next:
class ParentClass
attr_reader :user
def initialize(user)
@user = user
end
end
class ChildOne < ParentClass
attr_reader :token
def initialize(user, token)
super(user)
@token = token
end
end
This way the new variable token
will be available only for the ChildOne
class.
Also, known as scope resolution operator
.
When we work with namespace it's very common to override some objects, etc that we already have. This could cause us headaches when we try to access a specific object and that object has the same name as our namespace. To have a clearer idea, let's review the next example, imagine that we have the next nested modules:
module FHIR
module Services
module Appointment
def appointment
@appointment ||= Appointment.find(id)
end
end
end
end
If you do Appointment.find(id)
you will get an error similar to this:
NoMethodError: undefined method 'find' for FHIR::Services::Appointment:Module
.
That ^ is because the Appointment
is doing reference to the namespace FHIR::Services::Appointment
(local scope) instead of the Appointment
model (global scope).
The constant resolution operator
will help us to resolve this. If you put:
::Appointment.find(id)
This will work because is referencing the global namespace which is the Appointment model this way you can access directly to the model instead of the current namespace.
Learned by samantha-bello on Nov 5, 2021Sometimes we are working on a branch and we want a specific change in a specific commit that is not the last one, we could use fixup
to have our commits neat and to avoid doing a disaster with them.
Imagine that we have a commit story like this:
commit 30e9b16e098315e459f46313c099317ab74decbd
Author: Sam Belmor <sambelmor@gmail.com>
Date: Tue Sep 28 18:57:32 2021 -0500
Add the MVC architecture
commit e13f8600584a8b304c25d08bbaa13d1999f51569
Author: Sam Belmor <sambelmor@gmail.com>
Date: Tue Sep 28 18:51:06 2021 -0500
Add koa/node setup
commit b4b7ee003d554fa7eaa967bcf236c9a02c5a7249
Author: Yasser Batas <yassk8@gmail.com>
Date: Thu Jul 15 07:11:39 2021 -0500
Initial commit
If we do some changes related to the koa/node setup
and we want those changes in the second commit e13f8600584a8b304c25d08bbaa13d1999f51569
, to avoid doing another commit we could do the following:
git add .
you want your changes
For this example we want the changes in the commit Add koa/node setup
with the key e13f8600584a8b304c25d08bbaa13d1999f51569
.
git commit --fixup e13f8600584a8b304c25d08bbaa13d1999f51569
git log
You will see something like this:
commit 3ef0a9c5a3a67b5dff7a7f6374921babf7a40c12 (HEAD -> feature/#2-knex-setup)
Author: Sam Belmor <sambelmor@gmail.com>
Date: Thu Oct 21 11:50:35 2021 -0500
fixup! Add koa/node setup
commit 30e9b16e098315e459f46313c099317ab74decbd
Author: Sam Belmor <sambelmor@gmail.com>
Date: Tue Sep 28 18:57:32 2021 -0500
Add the MVC architecture
commit e13f8600584a8b304c25d08bbaa13d1999f51569
Author: Sam Belmor <sambelmor@gmail.com>
Date: Tue Sep 28 18:51:06 2021 -0500
Add koa/node setup
commit b4b7ee003d554fa7eaa967bcf236c9a02c5a7249
Author: Yasser Batas <yassk8@gmail.com>
Date: Thu Jul 15 07:11:39 2021 -0500
Initial commit
As you can see a new commit was added, with the difference that you'll see the fixup!
word before the commit's description
fixup! Add koa/node setup
At this point, you should check if this is the commit where you want your changes. If this is correct go-ahead to the next point if you made a mistake you could do:
git reset HEAD~
And start again. Be sure to copy the correct commit's key.
Now you're ready to squash your new changes with your old commit.
1. First, you need to copy the previous commit's key from the one that I want to do the squash
. For this example the key that I need is this key b4b7ee003d554fa7eaa967bcf236c9a02c5a7249
from this commit Initial commit
2. So you should put the following:
git rebase -i --autosquash b4b7ee003d554fa7eaa967bcf236c9a02c5a7249
When you do the previous command a text editor will open (nano, vim, etc), and you will see something like this:
pick e13f860 Add koa/node setup
fixup 3ef0a9c fixup! Add koa/node setup
pick 30e9b16 Add the MVC architecture
When you close that window, your changes will be saved and now you'll have the new changes in the corresponding commit.
Learned by samantha-bello on Oct 22, 2021For Each .forEach iterates the elements of an array but does not return a value.
const a = [1, 2, 3];
const newArray = a.forEach((num, index) => {
//do something
});
// newArray = undefined
Map .map iterates the elements of an array but return a new array.
const a = [1, 2, 3];
const newArray = a.map(num => {
return num * 2;
});
// newArray = [2, 4, 6]
Puma offers a way to query its internal stats by enabling a controll app in a separate port, this can be useful when we need to know if the app is alive, this is different than normal health check endpoints because it does not get processed by rails at all.
To enable this functionality, all you need to do is to add this line in your puma.rb file:
activate_control_app 'tcp://0.0.0.0:9293', { no_token: true }
It will start a second web server in the port 9293 that can be queried by monitoring tools or even balancer healthcheck.
ecruz@Edwins-MBP % curl 'http://127.0.0.1:9293/stats'
{"started_at":"2021-10-15T21:39:55Z","workers":2,"phase":0,"booted_workers":2,"old_workers":0,"worker_status":[{"started_at":"2021-10-15T21:39:55Z","pid":44969,"index":0,"phase":0,"booted":true,"last_checkin":"2021-10-15T21:40:05Z","last_status":{"backlog":0,"running":5,"pool_capacity":5,"max_threads":5,"requests_count":0}},{"started_at":"2021-10-15T21:39:55Z","pid":44970,"index":1,"phase":0,"booted":true,"last_checkin":"2021-10-15T21:40:05Z","last_status":{"backlog":0,"running":5,"pool_capacity":5,"max_threads":5,"requests_count":0}}]}%
ecruz@Edwins-MBP %
Check the documentation for more options/usages
Learned by Edwin Cruz on Oct 15, 2021Numberic separators is a new JavaScript feature that allows you to use underscores as separators to help to improve readability using a visual separation between groups of digits.
// A billion
const amount = 1_000_000_000;
// Hundreds of millions
const amount = 1_475_938.38;
// 6234500 cents (62345 dollars)
const amount = 62345_00;
// 1,734,500
const amount = 1_734_500;
// 20^30000
const amount = 2e30_000;
The event loop is the secret behind JavaScript's asynchronous programming. JS executes all operations on a single thread, but using a few smart data structures, it gives us the illusion of multi-threading but first we have to understand the Call Stack.
Call Stack
The call stack works based on the LIFO principle(last in first out) When you execute a script, the JavaScript engine creates a Global Execution Context and pushes it on top of the call stack.
function multiply(a, b) {
return a * b
}
function squere(n) {
return multiply(n, n)
}
function printSquere(n) {
var result = squere(n)
console.log(result)
}
printSquere(4)
**Stack**
4- multiply
3- squere
2- printSquere
1- main
Result: 16
Call Stack with async callbacks (Even loop)
The event loop facilitates this process; it constantly checks whether or not the call stack is empty. If it is empty, new functions are added from the event queue. If it is not, then the current function call is processed.
An example of this is the setTimeout method. When a setTimeout operation is processed in the stack, it is sent to the corresponding API which waits till the specified time to send this operation back in for processing.
console.log('hi')
setTimeout(()=> {
console.log('there')
},5000)
console.log('bye')
**Stack**
3- there
2- bye
1- hi
**webapis**
setTimeout callback(cb)
**taskqueue**
callback(cb)
**evenloop**
move cb to stack
In the example the setTimeout Callback enters the webapi stack executes and then goes to the task queue and waits for the stack to become empty and the event loop moves the callback to the stack.
Learned by leyaim-jimenez on Oct 1, 2021module_function
allows exposing instance’s methods so they can be called as they would be class methods.module User
def name
'Hello Sam'
end
end
If you try to do this:
user = User.new
user.name
You're gonna receive an error because modules
do not respond to the new
method.
You can use this useful method module_function
:
module User
module_function
def name
'Hello Sam'
end
end
And call the name
method like User.name
module_function
to use all the methods inside a module as class methods ormodule_function :name
to only apply it in a specific methodAnother option to do so is using extend self
instead:
module User
extend self
def name
'Hello Sam'
end
end
If JavaScript's built-in type coercion makes it true, thats mean that the values is a truthy.
true
{}
[]
42
"0"
"false"
new Date()
-42
12n
3.14
Infinity
-Infinity
and in Javascript a falsy value is a value that is considered false
false
0
0n: 0 as a BigInt
'': Empty string
null
undefined
NaN
According to rfc1035, underscores (_
) are not allowed as part of domain names.
The labels must follow the rules for ARPANET host names. They must start with a letter, end with a letter or digit, and have as interior characters only letters, digits, and hyphen (
-
). There are also some restrictions on the length. Labels must be 63 characters or less.
This means domain names like my_domain.com
or sub_domain.main-domain.com
are invalid.
Special thanks to @jclopezdev for finding this out.
Learned by kevin-perez on Sep 28, 2021In JavaScript null and undefined are rather strange values, both serve a very similar purpose, which is to indicate the absence of a value.
Null
Null is used to assign a reference to an object that you will no longer need or, directly, you want to have the variable declared but initialize it with a value that you still do not know what it will be exactly. In all these cases the best thing to do is to assign a null value.
var miVariable = null;
console.log(miVariable);
//log null
undefined
For undefined means that the variable is declared but its value has not yet been defined.
var miVariable
console.log(miVariable);
//log null
Both values are values of type false, so if you do a non-strict comparison you will get true undefined, which means that the variable is declared but its value has not yet been defined.
if (null == undefined) {
return true
}
//log true
and if you do a strict comparison, because they are not really the same, it returns a false:
if (null === undefined) {
return true
}
return false
//log false
This means that variable and function declarations are physically moved to the beginning of the code and are allocated in memory during the compilation phase.
function welcomeTo(name) {
console.log("Welcome to " + name);
}
welcomeTo("Magmalabs");
//returns welcome to magmalabs
As you can see hoisting allows you to use a function before declaring it in the code.
welcomeTo("Magmalabs");
function welcomeTo(name) {
console.log("Welcome to " + name);
}
//returns welcome to magmalabs
And also allows you to use a function after declaring it in the code.
For variables, hoisting only applies to the declaration, not to their assignment. example:
We declare the variable name but we got an undefined
console.log(name);
var name = magmalabs;
//return undefined
That’s because JavaScript only hoist the declaration
var name;
console.log(name);
name = magmalabs;
//return undefined
To avoid these errors, it is very important to keep in mind that hoisting only applies to the declaration.
Learned by leyaim-jimenez on Sep 17, 2021It is common to have multiple services listed in the docker-compose file, sometimes with dependencies, but also, a normal workflow sometimes is to just start everything, like:
docker-compose -f docker-compose.yml -d
And it will start all servies listed with their dependencies, but, what happens if you need to add another service and you do not need it to start along with the rest? The answer is: profiles:
services:
db:
image: pg
cache:
image: redis
rails:
depends_on:
- db
- cache
command: puma
sidekiq:
profiles: [ 'jobs' ]
depends_on:
- db
- cache
command: sidekiq
So, in this case, whenever you do docker-compose up -d
it will start only rails with its dependencies: db and cache, it wont start sidekiq by default, but if you really want to start sidekiq, then you need to explicitly type it: docker-compose up sidekiq -d
.
It is common to apply some extra scopes when fetching AR relationships, for examples, if we have countries and states, we might want all the countries starting with the letter A and all their states that starts with the letter B, this will automatically create a n+1 query problem since it nees to iterate over each country and fetch all states, but, Rails provides a way to eager load these associations easily:
states_scope = State.where("name ilike 'b%'")
countries = Country.where("name ilike 'a%'")
# This is the magic
ActiveRecord::Associations::Preloader.new.preload(countries, :states, states_scope)
# Now you can invoke coutries.each(:states) and it wont cause queries N+1
countries.map {|country| { country.id => country.states.size }
Normally, you would have to define another relationship in order to eager load the association, but it is not needed using this approach:
class Country < AR::Base
has_many :states
has_many :states_starting_with_b, -> { where("name ilike 'b%'") }, foreign_key: :state_id, class_name: "State"
end
# Then
Country.includes(:states_starting_with_b).where("name ilike 'a%'")
But this approach does not scale, it requires to define tons of relationships
Learned by Edwin Cruz on Sep 9, 2021If you need to add extra checks for services to be up and running before starting another one, you can use healtcheck property:
services:
pg:
image: pg/pg-12
ports:
- 5432:5432
healtcheck:
test: [ "CMD-SHELL", "pg_isready -U postgres" ]
interval: 5s
timeout: 5s
retries: 5
redis:
image: redis:5.0.4-alpine
ports:
- 6380:6379
healthcheck:
test: [ "CMD", "redis-cli", "ping" ]
interval: 5s
timeout: 5s
retries: 5
app:
image: railsapp
depends_on:
pg:
condition: service_healthy
redis:
condition: service_healthy
ports: ['3000:3000']
command: |
bash -c "bundle exec rails s"
TypeProf is a Ruby interpreter that abstractly executes Ruby programs at the type level. It executes a given program and observes what types are passed to and returned from methods and what types are assigned to instance variables. All values are, in principle, abstracted to the class to which the object belongs, not the object itself.
$ typeprof user.rb
# TypeProf 0.12.0
# Classes
class User
attr_accessor skip_add_role: untyped
def self.from_omniauth: (?Hash[bot, bot] auth) -> User
private
def assign_default_role: -> nil
end
$ typeprof skill.rb
# TypeProf 0.12.0
# Classes
class Skill
private
def acceptable_image: -> nil
end
$ typeprof ability.rb
# TypeProf 0.12.0
# Classes
class Ability
attr_accessor user: untyped
def initialize: (untyped user) -> untyped
private
def alias_actions: -> untyped
def register_extension_abilities: -> untyped
end
bundlde exec rails db:migrate:down VERSION=202101010000001
Where 202101010000001
is the migration you want to rollback
Recently I had the need to test Oauth with Facebook locally and after creating and configuring the App and everything was working wonderfully ...
until it was not.
Facebook now forces SSL so I had to setup it locally by creating a self signed certificate and running my server with it.
localhost.mumoc.crt
and localhost.mumoc.key
. Mumoc is my username in my working machine.name=localhost.$(whoami)
openssl req \
-new \
-newkey rsa:2048 \
-sha256 \
-days 3650 \
-nodes \
-x509 \
-keyout $name.key \
-out $name.crt \
-config <(cat <<-EOF
[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
CN = $name
[v3_req]
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = $name
DNS.2 = *.$name
EOF
)
Make sure to at least add digitalSignature
and keyEncipherment
to KeyUsage or you won't be able to use it in Chrome
config/ssl
directory inside my app folder)mv localhost.mumoc.* config/ssl
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain config/ssl/localhost.mumoc.crt
rails s -b 'ssl://localhost:3000?key=config/ssl/localhost.mumoc.key&cert=config/ssl/localhost.mumoc.crt'
When you're doing an INSERT
query, you could be trying to insert a row containing a primary key that already exists in the table. Instead of doing a previous query to see if the key exists or not, you could try ON DUPLICATE KEY UPDATE
.
INSERT INTO table (
field1,
field2
)
VALUES (
"foo",
"bar"
)
ON DUPLICATE KEY UPDATE
field1="foo",
field2="bar"
I'm developing an Android app as a side project and today I learned about adb forward
and adb reverse
. Basically, they allow you to forward or reverse traffic to specific ports between an Android device and your development machine.
Let's say I need my app to fetch something from http://localhost:3000/some-data
. When the app is running on the phone localhost
refers to the phone itself, and my server is running in my dev machine. So, if I do this:
adb reverse tcp:3000 tcp:3000
Now when the app tries to access localhost:3000
it will actually reach out to my dev machine's 3000
port. Very useful if you're developing the app's backend as well (as I am).
Similarly, if I wanted to access a server inside the phone from my dev machine, I could run:
adb forward tcp:5000 tcp:5000
And now if I run curl http://localhost:5000
in my dev machine it will hit the server running on the phone. Pretty neat!
I can run all tests from a file with:
yarn run cypress:run -s path/to/file.spec.js
but what about when I want to run only one test case from that file and not all of them?
We could use only()
// path/to/file.spec.js
it.only('just run this test', () => { ... })
it('not run this test', () => { ... })
// we could also use describe.only() but IDK if that is a bug or a feature xD
Run again yarn run cypress:run -s path/to/file.spec.js
to see how the it.only()
test will run it
As a UX designer, the product you create will constantly compete for users’ attention. If users are paying attention to one thing, like a notification on their mobile phone, it means they’re ignoring something else, so users have to be selective about how they spend time! This battle over users’ attention is referred to as the attention economy.
The term attention economy originated with psychologist and Nobel Laureate Herbert A. Simon, who believed that there are limits on what humans can think about and do at one time. Many scientists believe that humans aren’t very good multitaskers; technology should help users, not distract them. The more distracted a person is, the less likely they are to complete a task well.
Learned by aldo-mosqueda on Jun 14, 2021I was using Axios to test an API created in Rails, trying to set up cookies for a User Authentication process. After attempting to get the information back i realize that the cookie was not persistent, due to the lack of one parameter... withCredentials: true
So if you want your session to store cookies in the client side and have them available remember to pass it to the call import axios from
import axios from 'axios'
axios.post(API_SERVER + '/login', { email, password }, { withCredentials: true })
Otherwise the cookie would not be saved.
Today I learn the Mehrabian 7-38-55 rule. The rule states that: 7% of meaning is communicated through spoken word 38% through tone of voice, and 55 % through body language.
It was developed by psychology professor Albert Mehrabian at the University of California, Los Angeles.
So... it is always a good idea to keep our cameras on at every meeting ;)
Learned by aldo-mosqueda on May 28, 2021Well, it turns out that installing capybara-webkit gem can give you different problems, in my case I had to install
capybara-webkit -v '1.15.1'
.
You need to install QT as a dependecy.
The latest versions of QT including 5.6 returns the following message:
QtWebKit is no longer included with Qt 5.6
I followed one of our guides here, however it appears that QT version 5.5 was removed.
cd $( brew --prefix )/Homebrew/Library/Taps/homebrew/homebrew-core
git checkout 9ba3d6ef8891e5c15dbdc9333f857b13711d4e97 Formula/qt@5.5.rb
brew install qt@5.5
curl: (22) The requested URL returned error: 404
Error: Failed to download resource "qt@5.5_bottle_manifest"
Download failed: https://ghcr.io/v2/homebrew/core/qt/5.5/manifests/5.5.1_1
I also tried through binary installer but I got the following error:
Error creating SSL context
I finally succeeded, installing an older version
brew tap cartr/qt4
brew install qt@4
brew install qt-webkit@2.3
gem install capybara-webkit -v '1.15.1'
Building native extensions. This could take a while...
Successfully installed capybara-webkit-1.15.1
1 gem installed
While debugging a cucumber test (within an specific step for an specific scenario) with a binding.pry I wanted to see the html as it is with inputs and outputs of data at the moment (and because I usually run tests with Capybara headless option), I realized the existance of:
save_and_open_page
it Saves a snapshot of the page and open it in a browser for inspection
https://www.rubydoc.info/github/jnicklas/capybara/Capybara%2FSession:save_and_open_page
Note: ^ be sure to have the gem 'launchy' within test env so that it works
Learned by victor-delarocha on May 12, 2021If you installed any version above 5.6 make sure you uninstall all those versions, for instance:
MacBook-Air:myproject heridev$ brew uninstall qt
Uninstalling /usr/local/Cellar/qt/6.0.3_2... (8,233 files, 158.7MB)
MacBook-Air:myproject heridev$ brew uninstall qt@5
Uninstalling /usr/local/Cellar/qt@5/5.15.2... (10,688 files, 367.9MB)
Then we need to install the 5.5 version (old version):
cd $( brew --prefix )/Homebrew/Library/Taps/homebrew/homebrew-core
git checkout 9ba3d6ef8891e5c15dbdc9333f857b13711d4e97 Formula/qt@5.5.rb
// this will install the qt from shopify/shopify
brew install qt@5.5
And make sure you add the qt PATH in my case:
echo 'export PATH="/usr/local/opt/qt@5.5/bin:$PATH"' >> /Users/heridev/.bash_profile
source ~/.bash_profile
Now, you should be able to install the capybara webkit gem without any problems
Learned by heriberto-perez on May 5, 2021As a [UX Designer] I want to [embrace Agile] so that [I can make my projects user-centered]
TIL that User Stories were originated as part of the Agile and SCRUM development methodologies. A tool so simple yet so powerful, it is a great design method that enhances collaboration.
Read the entire article: https://bit.ly/3tkB3RE
Learned by aldo-mosqueda on May 5, 2021You can easily tell Rails to control email delivering with a custom mailer interceptor, all you need to do is to implement the class method delivering_email
:
class DeliverOrNotEmailInterceptor
def self.delivering_email(email)
mail.perform_deliveries = !email.to.end_with?('special-domain.com')
end
end
# config/initializer/email_interceptors.rb
ActionMailer::Base.register_interceptor(DeliverOrNotEmailInterceptor)
I never heard of this until today.
It's an initiative for knowing the people behind a website. It's a TXT file that contains information about the different people who have contributed to building the website.
If you are using Ruby 2.3.0
or above
Now instead of doing this:
result.try(:[], 'avatar').try(:[], 'model').try(:[], 'raw_attributes').try(:[], 'signup_state')
# or
result && result['avatar'] && result['avatar']['model'] && result['avatar']['model']['raw_attributes'] && result['avatar']['model']['raw_attributes']['signup_state']
Now you can easily do the same with dig
:
result.dig('avatar', 'model', 'raw_attributes', 'signup_state')
1.- Create a gist
2.- Clone your gist:
# make sure to replace `<hash>` with your gist's hash
git clone https://gist.github.com/<hash>.git # with https
git clone git@gist.github.com:<hash>.git # or with ssh
3.- Open it & move your image
cd <hash>
mv ~/Desktop/image.jpg ~/Projects/gist/image.jpg
4.- Add your image to your gist's repository:
git add image.jpg
5.- Commit the image:
git commit -m "Add image"
6.- Update gist:
git push origin master
Quick example, to see and understand better how an ActiveRecord query using scopes or methods in the model works at the SQL level and how to run it, all in the same example
Let say you have a database with users and you have some scopes to filter by non-demo, active, and completed providers with a specific Role (CanCanCan behind the scenes) :
User.providers.real.active.completed
If we run this command
irb(main):007:0> User.providers.real.active.completed.to_sql
We would get this:
=> "SELECT \"users\".* FROM \"users\" INNER JOIN \"users_roles\" ON \"users_roles\".\"user_id\" = \"users\".\"id\" INNER JOIN \"roles\" ON \"roles\".\"id\" = \"users_roles\".\"role_id\" WHERE (roles.name = 'Provider') AND \"users\".\"demo_account\" = 'f' AND (\"users\".\"organization_id\" NOT IN (SELECT \"organizations\".\"id\" FROM \"organizations\" WHERE \"organizations\".\"demo_account\" = 't' ORDER BY \"organizations\".\"name\" ASC)) AND \"users\".\"is_active\" = 't' AND \"users\".\"signup_state\" = 'Completed'"
Then we just need to replace the invalid characters such as \
and translate that into a SQL version like this:
SUMMARY_PROVIDERS_REPORT_SQL = <<-SQL
WITH real_providers AS
( SELECT users.* FROM users
INNER JOIN users_roles ON users_roles.user_id = users.id
INNER JOIN roles ON roles.id = users_roles.role_id
WHERE (roles.name = 'Provider') AND users.demo_account = 'f'
AND (users.organization_id NOT IN (
SELECT organizations.id FROM organizations WHERE organizations.demo_account = 't' ORDER BY organizations.name ASC)
)
AND users.is_active = 't' AND users.signup_state = 'Completed')
select real_providers.id, real_providers.name from real_providers
SQL
In order to run it in the Rails console for example:
report_results = ActiveRecord::Base.connection.execute(SUMMARY_PROVIDERS_REPORT_SQL)
report_results.entries
That will give you the id
and name
of all those valid providers
if you need to know whether to use a pre-laoded collection using eager loading or fech the collections, you can always call loaded? method:
if user.contact_phones.loaded?
user.contact_phones.detect? {|phone| phone.primary }
else
user.contact_phones.find_by(primary: true)
end
When we apply the same style to multiple selectors on CSS we use to do something like this:
.section-header h1,
.section-header span,
.section-header .heading {
line-height: 1.2;
}
.navigation li,
.navigation p {
padding: 5px 10px;
}
With :is() we can write our CSS in a shorter way.
.section-header :is(h1, span, .heading) {
line-height: 1.2;
}
.navigation :is(li, p) {
padding: 5px 10px;
}