19,634 Matching Annotations
  1. Sep 2023
    1. the Senate passed the bill by unanimous consent, although several senators stated later that they would have objected if they had known that the bill could pass

      This doesn't make sense. Why would you vote for it if you object for it? Just vote what you really mean.

    1. commands="\nthing1@this is thing 1\!\nthing2@this is thing 2!" while read line;do // do your stuff here line <<< $( echo -e "${commands}" )

      Seems to work. Not used to the <<< expression...

    2. -e switch tells the echo command to honour all back slashes . The same behaviour can be achieved with `shopt -s xpg_echo` ( you have to remove -e switch whenever you do that )
    3. Starting in bash 4.4, you can use ${input@E} in place of $(echo -e "$input").
    1. I am a developer, mainly on embedded systems, with a computer science background and security and cryptography leanings by trade. I also have interests in various other topics.
    1. Using quotes for i in "$(cat $1)"; results in i being assigned the whole file at once. What should I change?
    2. files with characters after the last newline are not text files, and those characters don't constitute a line. In many cases those bogus characters are better left ignored or removed, though there are cases where you may want to treat it as a extra line, so it's good you show how.
    3. (9 years later:)Both provided answers would fail on files without a newline at the end, this will effectively skip the last line, produce no errors, would lead to disaster (learned hard way:).
    4. Answers are identical because Questions are identical too !
    1. If IFS is unset, or its value is exactly <space><tab><newline>, the default, then any sequence of IFS characters serves to delimit words. If IFS has a value other than the default, then sequences of the whitespace characters space and tab are ignored at the beginning and end of the word, as long as the whitespace character is in the value of IFS (an IFS whitespace character). Any character in IFS that is not IFS whitespace, along with any adjacent IFS whitespace characters, delimits a field. A sequence of IFS whitespace characters is also treated as a delimiter. If the value of IFS is null, no word splitting occurs.
    1. Also, always prefix globs with "/" or "./"; otherwise, if there's a file with "-" as the first character, the expansions might be misinterpreted as options.
    1. Don’t send test phishing messages or test campaigns from your domain. Your domain’s reputation might be negatively affected, and your domain could be added to internet blocklists.

      What does a test compaign mean exactly? Can't I send test messages without fear? Isn't sending tests essential prior to sending a live message to all recipients?

    1. A good analogy for your email reputation is your personal credit score. Obviously, a bad reputation will hurt you. However, not having a reputation will also hurt you. If ESPs don’t know you (or more specifically your IP and domain) they will assume the worst and filter you, at least initially. It’s tough to blame them given all the spam out there. Due to the importance of reputation, a significant portion of our discussion on best practices revolves around building and maintaining your email reputation.
    2. We dream of a day when IP reputation does not matter and we can rely on domain reputation, but unfortunately we are not there yet.
    1. if at all possible, you should send MIME attachments instead, unless you specifically strive to be able to communicate with the late 1980s.
    2. Back in the day, the de facto standard for sending binaries across electronic mail was uuencode. It still exists, but has numerous usability problems; if at all possible, you should send MIME attachments instead, unless you specifically strive to be able to communicate with the late 1980s.
    1. There is actually no meaningful distinction between a hostname which happens to be a second-level domain and a hostname which has more parts than that. You can even have a machine at a top-level domain if you happen to be a small country or otherwise are able to create an A record for one.
    1. The host itself does not handle the actual FQDN. That is handled by the DNS. FQDN (Fully Qualified Domain Name) is handled by DNS translating names into IP addresses. Using the /etc/hosts file, you are essentially overriding the DNS server.
    1. To ensure your messages pass the DMARC check with flying colors, you'll need to make certain the domains listed in the From, Sender, and Mail-From headers match each other exactly. That is, the domain listed in the From header is the exact actual sending domain.
    2. For example, if your sending domain is ABCdomain.com, but your From field shows 123domain.com instead, you will almost certainly run into DMARC issues. Sometimes, even the difference between mail.ABCdomain.com and ABCdomain.com is sufficient for a server to place your message in a spam folder. We make sure that our Email Best Practices are clear that the domain listed in the From header and the actual sending domain should match for exactly this reason.
    1. Note that the mere presence of this header causes premailer to be skipped, i.e., even setting skip_premailer: false will cause premailer to be skipped. The reason for that is that the skip_premailer is a simple header and the value is transformed into a string, causing 'false' to become truthy.

      They should fix this!

      lib/premailer/rails/hook.rb def skip_premailer_header_present? message.header[:skip_premailer] end

    1. sums = [0] (1..gains.length).each do |i| sums[i] = sums[i - 1] + gains[i - 1] end could, if scan was introduced, be replaced with: sums = gains.scan_left(0, &:+)
    2. I'd even go as far as saying each_with_object is often less readable than using a captured variable.

      elaborate? what is a captured variable? I assume he means the val = 0 from outside the scope of the block, which was "captured" in the closure.

    3. I think "purely functional, not a single re-assigned variable" often introduces significant extra complexity, when Ruby is a language that embraces both functional and imperative programming.
    4. One of my favorite aspects of Ruby is how easy it is to write in a functional programming style, and including the scan operation would expand the number of use cases covered by functional methods.
    5. each_with_object is only useful if mutating some object (typically an Array or Hash).

      typically true... is it always true?

    6. I think this is the crux of the issue. Because #inject needs to evaluate every element in order to return a meaningful value, it can't be partially evaluated. The "scan" operation allows for partial evaluation.
    7. I think there are real-world use cases! Would you consider converting a history of transactions into a history of account balances a valid use-case? That can be done easily with a scan. For example, if you have transactions = [100, -200, 200] then you can find the history of account balances with transactions.scan_left(0, &:+) # => [0, 100, -100, 100].
    1. Circuit representation of a work-efficient 16-input parallel prefix sum
    1. The key differences between #inject and #scan_left are: Incremental results: #scan_left returns a series of results after processing each element of the input series. #inject returns a single value, which equals the final result in the series returned by #scan_left. Laziness: #scan_left can preserve the laziness of the input series. As each incremental result is read from the output series, the actual calculation is lazily performed against the input. #inject cannot be a lazy operation in general, as its single result reflects a calculation across every element of the input series.
    1. def self.make_lazy(*methods) methods.each do |method| define_method method do |*args, &block| lazy.public_send(method, *args, &block) end end end
    2. I want the fact that my collection is lazy to be an implementation detail.
    1. In order to enable MPP, users must have Apple devices, configure their email account to use Apple Mail applications, update their operating system to the latest version, and opt into MPP. 
    1. In other words, when a recipient clicks the “unsubscribe” link in your email, the recipient’s mail client will send an email to this address. It is your responsibility to receive and process these generated emails.
    2. You must include at least the mailto portion of the List-Unsubscribe header, since some services only support this portion (iOS, for example). However, many inbox providers and mail clients honor both methods. To ensure that the greatest number of your recipients have the ability to unsubscribe from your emails, thus protecting your reputation as a sender, we recommend including both mailto and http.
    3. You must include at least the mailto portion of the List-Unsubscribe header, since some services only support this portion (iOS, for example). However, many inbox providers and mail clients honor both methods. To ensure that the greatest number of your recipients have the ability to unsubscribe from your emails, thus protecting your reputation as a sender, we recommend including both mailto and http.
    4. It is possible to use the List-Unsubscribe header even if you do not want to use subscription tracking. This is useful for users who want to provide their recipients an easy way to unsubscribe from their emails without relying on SendGrid’s tracking features. Continue reading below for an explanation of the List-Unsubscribe header, and how you can use it when sending email via SendGrid.
    5. List-Unsubscribe is a small piece of text that can be inserted in the header section of your email. The List-Unsubscribe header will insert an “unsubscribe” button, or link, next to the From address at the top of your email. A recipient can click this link to notify you that they would like to unsubscribe from your emails.
    1. List-unsubscribe can help reduce spam complaints.If subscribers can’t find the unsubscribe link, they may click the spam reporting button instead. This could hurt your email deliverability and sender reputation. To mailbox providers, a spam complaint is a spam complaint, regardless of whether the recipient actually perceived the message as malicious.
    2. Support for list-unsubscribe varies across email clients.
    1. If anything in this policy does not fit with your own local policy, you should not use dnswl.org for whitelisting or similar purposes.
    1. Apparently, Google uses some additional heuristics to decide whether the link should be displayed or not. The List-Unsubscribe header could be abused by spammers to validate that their target got the message, and thus, GMail only shows the unsubscribe link if the source of the message has accumulated sufficient trust.

      Shouldn't it be controllable by the end user, in the same way that they can press a button to show all images if images are blocked by default for security/privacy reasons??

    1. DKIM has proven to be a highly effective means by which a receiver can verify that the signed fields of an email have not been modified in transit. DKIM is as secure as the weakest link - the private key, though. The private key of a DKIM keypair is vulnerable to being stolen if an attacker is able to compromise the system in which it is stored. Therefore, to minimize the risk of active DKIM keys being compromised, they should be changed frequently. This is a practice known as DKIM key rotation. Each time a key is rotated, a new {selector, private key, public key} tuple is created. Then the public key will need to be published in the DNS, and you need to re-configure the outgoing email server to use the new private key. After this is done, the outgoing email server will use the new private key to sign all outgoing email messages.
    2. Multiple private/public key pairs are required due to the following reasons: DKIM key rotation which we will explain in the next section; setting up DKIM with multiple email delivery services on a single domain; each service can have their own separate selectors so that signing/verifying with one service doesn't interfere with that with another.
    3. a tuple { selector, private key, public key } is created
    1. A record can be viewed as the computer analog of a mathematical tuple, although a tuple may or may not be considered a record, and vice versa, depending on conventions and the specific programming language.
    2. An object in object-oriented language is essentially a record that contains procedures specialized to handle that record; and object types are an elaboration of record types. Indeed, in most object-oriented languages, records are just special cases of objects, and are known as plain old data structures (PODSs), to contrast with objects that use OO features.
    3. A record type is a data type that describes such values and variables.
    4. In type theory, product types (with no field names) are generally preferred due to their simplicity
    1. Most typed functional programming languages implement tuples directly as product types
    1. Start with the default gemfile: gem "rails", "~>x.x.x" Replace the xes with the actual version of rails that you need. It'll be in config/environment.rb, unless it's a Rails 3 app, in which case you can just put 3.0.0. Start your app, and watch for errors. When there's an error about not being able to load something, add that gem to the gemfile. Eventually, you'll have the whole list. :)
    1. Each message you send out has both the sender and from address. Simply put, the sender domain is what the receiving email server sees when initiating the session, and the from address is what your recipients will see.
    2. For better deliverability it is recommended to use the same from domain as the sender,
    3. Domain names do not matter as much if you’re only sending. You can send messages from sales@mycompany.com even if your domain name is called anothercompany.org. Although, it is best for deliverability if you are using the same domain in the From field that the actual sender is using.
    1. Each message you send out has both the sender and from address. The sender domain is what the receiving email server sees when initiating the session. The from address is what your recipients will see. For better deliverability it is recommended to use the same from domain as the sender.
    1. However, if the previous user was also the Account Owner, the previous user will need to promote a different user to the Account Owner role. After that, the previous user can finally be deleted.
    1. Ultimately, the "On Behalf Of" notation highlights the mismatch between the domain used in the Sender field (mail.example.com) and the domain used in the From field (example.com).  In the above example, the envelope is sent through the domain mail.example.com, but the message is listed as being sent from the domain example.com.
    2. This nuance is important as the Sender field is an envelope field and the From is an email header field - each representing different aspects of the message. 
    3. there is no way for Mailgun to prevent an email client from displaying the "On Behalf Of" notation as long as the domains contained in the Sender and From fields don't match.  However, ensuring the exact same domain is used in both fields will eliminate the "On Behalf Of" notation.
    1. Migration from pre-exisiting non-flatpak installations In order to migrate from pre-exisiting non-flatpak installation and preserve all settings please copy or move entire ~/.thunderbird folder into ~/.var/app/org.mozilla.Thunderbird/.thunderbird In case Thunderbird opens a new profile instead of the existing one, run: flatpak run org.mozilla.Thunderbird -P then select the right profile and tick "Use the selected profile without asking on startup" box.
    1. I'm using Kubuntu 23.04, do not use Snaps, and wish to update to Thunderbird 115 from the installed version 102. Is this possible? It appears as if Ubuntu have stopped providing non-Snap packages for mainstream apps and Thunderbird themselves offer me a tar.bz2 whilst I'd rather use packaged apps. Will Thunderbird 115 be available as an official .deb file at all; will it be in the repos? What's the best non-Snap way to install it and keep it updated?
    1. Send on behalf of another user or account  Uncheck Treat as an alias. Example: You manage 2 email addresses in separate accounts or mail systems. You sign in to each account separately to read messages. But you want the convenience of sending mail as either address from your Gmail account.
    1. Users with unprivileged credentials who properly execute "sudo" (for example) to perform authorised administrative activities are also "escalating privilege". It is not only an exploit or a bug.
    2. There are many examples of a user's or process's privileges being elevated/escalated by design. - sudo in general - GitHub's "sudo mode" - https://en.wikipedia.org/wiki/Setuid:
    3. I dispute that there's a such thing as "horizontal privilege escalation", and not just because the term is a bit of an oxymoron.
    1. They are often used to allow users on a computer system to run programs with temporarily elevated privileges to perform a specific task. While the assumed user id or group id privileges provided are not always elevated, at a minimum they are specific.
    2. This allows the system designer to permit trusted programs to be run which a user would otherwise not be allowed to execute.
    1. “If somebody sends me something like that I’ll immediately erase it and say, ‘Please, sorry, do not send me things of people doing me,’” Anderson said in an interview with The Times. “Because I do not want to look at it, thinking, ‘Is that what I do? Is that what I mean?’ I don’t want to see too much of someone else thinking about what I try to be because, God knows, I could then start doing it.”
    2. “What it does is it sucks something from you,” he said of A.I. “It takes something from your soul or psyche; that is very disturbing, especially if it has to do with you. It’s like a robot taking your humanity, your soul.”
    1. During the discussion, Musk latched on to a key fact the team had discovered: The neural network did not work well until it had been trained on at least a million video clips.
    2. By early 2023, the neural network planner project had analyzed 10 million clips of video collected from the cars of Tesla customers. Did that mean it would merely be as good as the average of human drivers? “No, because we only use data from humans when they handled a situation well,” Shroff explained. Human labelers, many of them based in Buffalo, New York, assessed the videos and gave them grades. Musk told them to look for things “a five-star Uber driver would do,” and those were the videos used to train the computer.
    3. The “neural network planner” that Shroff and others were working on took a different approach. “Instead of determining the proper path of the car based on rules,” Shroff says, “we determine the car’s proper path by relying on a neural network that learns from millions of examples of what humans have done.” In other words, it’s human imitation. Faced with a situation, the neural network chooses a path based on what humans have done in thousands of similar situations. It’s like the way humans learn to speak and drive and play chess and eat spaghetti and do almost everything else; we might be given a set of rules to follow, but mainly we pick up the skills by observing how other people do them.
    4. Instead of being based on hundreds of thousands of lines of code, like all previous versions of self-driving software, this new system had taught itself how to drive by processing billions of frames of video of how humans do it, just like the new large language model chatbots train themselves to generate answers by processing billions of words of human text.
    1. A new class for containing value objects: it is somewhat similar to Struct (and reuses some of the implementation internally), but is intended to be immutable, and have more modern and cleaner API.
    2. # Note that it could be in `args.first`, or in `kwargs[:id]` now, so it is either this: def initialize(*args, **kwargs) if !args.empty? args[0] = args[0].to_i elsif kwargs.key?(:id) kwargs[:id] = kwargs[:id].to_i end super(*args, **kwargs) end
    3. Time.new('2023-01-29 00:29:30') # => 2023-01-29 00:29:30 +0200
    4. Before Ruby 3.2, there core class Time provided no way to to get back a Time value from any serialization, including even simple Time#inspect or #to_s. The Time.parse provided by standard library time (not core functionality, doesn’t work with explicit require 'time'), and tries to parse every imaginable format, while Time.new with string is stricter.
    5. string ones are those most of the Rubyists remember.
    6. Low-level processing of strings (like networks middleware, or efficient search algorithms, or packing/unpacking) might need an ability to operate on a level of single bytes, regardless of original string’s encoding. It is especially important while handling variable-length encodings like UTF-8. Before methods introduction, the only way to perform byte-level processing was to forcing string encoding into ASCII-8BIT, process, and then force encoding back.
    7. There are many simple use cases like pagination (when “21 items / 10 per page” should yield “3 pages”).
    8. It seems that the method is a direct equivalent of a.fdiv(b).ceil, and as such, annoyingly unnecessary, but fdiv, due to floating point imprecision, might produce surprising results in edge cases
    9. Note that used_refinements is a class method of a Module, and put there just for organizational purposes, while returning refinements list of the current context. There is no way to ask arbitrary module which refinements it uses (e.g., there is no Calculator.used_refiments).
    10. make_a_class::CONST = 42.tap { puts "Calculating the value" } # Prints: # In Ruby 3.1: # Calculating the value # Making a class # In Ruby 3.2: # Making a class # Calculating the value # Even simpler: NonExistentModule::CONST = 42.tap { puts "Calculating the value" } # Ruby 3.1: # Prints "Calculating the value" # raises "uninitialized constant NonExistentModule" (NameError) # Ruby 3.2: # just raises "uninitialized constant NonExistentModule" (NameError)
    1. I do not disagree, but I would also like to point out that it can confuse newbies, e. g. when they wonder whether they should use class_eval or instance_eval. Some concepts are not trivial to remember offhand.
    2. For me, I don't have an issue, but there was one syntax situation I found awkward: I need to sometimes know whether it is a class or a module that I am modifying. So I may have code: module Foo module Bar class Baz versus: class Foo::Bar::Baz It's not a huge issue, but ruby would yield an error if I specify a class or module incorrectly (which can happen if you spread code out into different .rb files, so I understand why there is an error message shown, to avoid accidents). But I then also wondered why I have to care whether it is a module or class, if my primary goal is to modify something, such as by adding a method. If I want to add a method: def foobar; end then I really should never be required to have to know whether I am modifying a class or a module.
    3. As "module" is more generic concept than "class", the name misleadingly implies that either this method doesn't returns refined modules, or modules can't be refined. This is obviously not true and trivially disproved: module Refs refine Enumerable do def foo = puts 'foo' end end Refs.refinements[0].refined_class #=> Enumerable. Which is, well, not a class. # The refinement is usable, so it is not a mute concept: using Refs [1, 2, 3].foo # prints "foo" successfully I believe we refer to "modules" when some feature applies to modules and classes. Unless there is some deeper consideration for the current naming (I don't see justification in #12737, but I might miss something), the method should be renamed or aliased.
    1. Customer service 24/5 follow the sun

      first sighting: 24/5 and follow the sun

    1. Leaky Bucket is implemented similarly to Token Bucket where OVER_LIMIT is returned when the bucket is full. However tokens leak from the bucket at a consistent rate which is calculated as duration / limit. This algorithm is useful for metering, as the bucket leaks allowing traffic to continue without the need to wait for the configured rate limit duration to reset the bucket to zero.
    1. Essentially, @mac.com is legacy users and was in place from the debut of osX to late 2000s. It required a annual paid subscription to have an email address, lol. Then the short-lived mobileMe era happened, which lasted only a couple years before Apple retracted and replaced it with iCloud, a much more sweeping service. MobileMe was also a paid subscription and included primordial versions of photo sharing and web hosting, etc. The iCloud era starting in 2012 finally ushered in free email addresses and free operating system updates. That's when the business model of large tech companies turned more into user accumulation wars to see who can attract the most subscribers and retain them in their ecosystem of products.
    2. The iCloud era starting in 2012 finally ushered in free email addresses and free operating system updates. That's when the business model of large tech companies turned more into user accumulation wars to see who can attract the most subscribers and retain them in their ecosystem of products.
    1. You can no longer create accounts with Yahoo domains other than "@yahoo.com",
    2. I'm curious: what is the reason for Yahoo discontinuing the "@ymail.com" domain?I'm aware that there's now a 2nd domain option available, "@myyahoo.com", and I recently took advantage of that to create a new address. But "@ymail.com" honestly looks more appealing to me than either of the "yahoo" iterations.
    1. # This helper allows you to reliably highlight text within a given Element by # simulating mouse actions. # module Features module HighlightContentHelper def highlight_content(node) height = node.native.rect.height width = node.native.rect.width page.driver.browser.action .move_to(node.native, -(width / 2), -(height / 2)) .click_and_hold .move_by(width, height) .release .perform end
    1. But you can't configure Standard Ruby. You can take it or leave it. If this seems presumptive, constraining, and brusque: you're right, it usually does feel that way at first.
    1. I'd suggest that you play around a little bit with a vanilla app. Create a brand new app without any additional files, just what rails new generates. See how bin/rails runner Models raises an error because there is no models directory in autoload_paths. Now, put config.autoload_paths += %W(#{config.root}/app) in config/application.rb and observe how bin/rails runner Models just returns a prompt. With the confidence of having that running, then transalate to your app.
    1. Root directories are recommended not to be nested; however, Zeitwerk provides support for nested root directories since in frameworks like Rails, both app/models and app/models/concerns belong to the autoload paths. Zeitwerk identifies nested root directories and treats them as independent roots. In the given example, concerns is not considered a namespace within app/models. For instance, consider the following file: app/models/concerns/geolocatable.rb should define Geolocatable, not Concerns::Geolocatable.
    1. Should any one stumble upon this issue @tenderlove reverted commit a8bf129 in a71350c which is in v5.0.0.beta1 and later.
    2. I agree with this statement so much. We should absolutely be failing hard rather than forcing people to debug thread safety issues at runtime. I can't think of anything more infuriating than debugging an issue that happens "sometimes".
    3. The problem is that in the case where an app is multi-threaded, and we don't switch off autoload, the case would be that it probably won't blow up, but random stuff will mysteriously sometimes fail in weird ways. So ask yourself this, what would you rather want, option 1) where you can get an exception at runtime, or option 2) where you get random, unpredictable, weird, hard to explain, difficult to debug bugs at runtime. Personally, I'm going to choose option 1. The downside of thread-safety issues is so much worse than the downside of the possibility of an exception. The way you're handling it makes it sound as though thread-safety is not important, as though Rails is still optimizing for the single-threaded case. That seems like a huge step back.
  2. Aug 2023
    1. async is a concurrency technique. If you need concurrency, async is required for node to work properly (not "better"). If you don't have concurrency, you don't need async. The point is you need to actually understand what async does for you and why. It's not inherently "better" for no reason and you don't need to memorize it as a "best practice". If the OP is writing a command line utility to alter a JSON file then exit, async complicates the code for no reason as the concurrency is not required.
    2. The question is also not about error handling and if the file write fails, exiting with a stack trace is reasonable default behavior because there's not much you can do to recover from that.
    3. async vs. sync depends exactly on what you are doing in what context. If this is in a network service, you need async. For a command line utility, sync is the appropriate paradigm in most simple cases, but just knee-jerk saying "async is better" is not correct. My snippet is based on the OP snippet for context.
    1. If you want to mimic a more production like situation you might use this workflow: Create a package of your submodule locally: cd /path/to/your/module npm pack This will create a .tgz file of your package in /path/to/your/module Install the local package of the submodule in your application: cd /path/to/your/application npm install /path/to/your/module/<YourModule>-<YourModulesVersion>.tgz
  3. www.npmjs.com www.npmjs.com
    1. We value conscious curation of our library size, and balancing performance and functionality. To that end, we cannot accept every suggestion. When evaluating pull requests we consider:
    1. While this works, it’s not a great developer experience. In development, we don’t always know ahead of time all the packages that need to be linked. Or keep track of the previously linked packages.This confusing behavior compounds to the poor usability and predictability of npm link.
    2. footguns
    3. npx link is a tool I developed as a safer and more predictable alternative to npm link.
    1. Serializing the data with a function specialized to your data shape can be more than 10x compared with JSON.stringify.
    1. The point of acts_as_paranoid is keeping old versions around, not really destroying them, so you can look at past state, or roll back to past version. Do you consider the attached file part of the state you should be able to look at? If you roll back to past version, should it have it's attachment there too, in the restored version?
    2. I think the problem with after_destroy is that it is triggered before the database commits. This means the change may not yet be seen by other processes querying the database; it also means the change could be rolled back, and never actually commited. Since shrine deletes the attachment in this hook, that would mean it might delete the attachment prematurely, or even delete the attachment when the record never ends up destroyed in the database at all (in case of rollback), which would be bad. For shrine's logic to work as expected here, it really does need to be triggered only after the DB commit in which the model destroy is committed.
    1. extensible plugin system.
    2. Modular design – the plugin system allows you to load only the functionality you need
    3. Shrine was heavily inspired by Refile and Roda. From Refile it borrows the idea of "backends" (here named "storages"), attachment interface, and direct uploads. From Roda it borrows the implementation of an extensible plugin system.
    1. 4. Too much couplingAnother issue I had with this is the coupling that it might introduce in your code. I do understand that our community in general is not very much interested in dealing with coupling and I am not an expert at this either, but I do get a feeling that this suppress method would lead to some very bad usages.For instance, why does the Copyable module needs to know about a class named Notification?
    1. In these other tests we do not care what was passed to the Load method so specify a “don’t care” with It.IsAny.
    2. Michael Sorens is passionate about productivity, process, and quality. Besides working at a variety of companies from Fortune 500 firms to Silicon Valley startups, he enjoys spreading the seeds of good design wherever possible, having written over 100 articles, more than a dozen wallcharts, and posted in excess of 200 answers on StackOverflow.
    1. As you say, you can use after_add and after_remove callbacks. Additionally set after_commit filter for association models and notify "parent" about change. class User < ActiveRecord::Base has_many :articles, :after_add => :read, :after_remove => :read def read(article) # ;-) end end class Article < ActiveRecord::Base belongs_to :user after_commit { user.read(self) } end
    2. As you say, you can use after_add and after_remove callbacks. Additionally set after_commit filter for association models and notify "parent" about change. class User < ActiveRecord::Base has_many :articles, :after_add => :read, :after_remove => :read def read(article) # ;-) end end class Article < ActiveRecord::Base belongs_to :user after_commit { user.read(self) } end
    1. It may seem like Testing is some sort of beta, unstable version but that’s not entirely true. Debian Testing is the next Debian stable version. The actual development branch is the Debian Unstable (also known as Sid). Debian Testing lies somewhere in between the unstable and stable branch where it gets the new features before the stable release.
    1. ActiveStorage has a different approach than what is suggested by @dhh here. The idea there seems to be to rule out a default and to explicitly set ActiveStorage::Current.url_options or by include ActiveStorage::SetCurrent. I don't understand why and asked about it in the Rails Forum. Maybe someone here can point out why we don't use a sensible default in ActiveStorage?
    1. Because Active Storage gem does not specify AWS SDK as its dependency, it’s quite possible you updated Active Storage while leaving AWS SDK behind (happened to me).
    2. You probably solved not because of using aws-sdk gem instead of aws-sdk-s3 but simply because you updated the SDK. I’m sure just updating the aws-sdk-s3 would solved too.
    1. Although it is possible to manually craft all the necessary HTTP requests to get the signed keys and manually upload the file to the storage backend, thankfully we don’t have to. Rails already provides us with the @rails/active_storage package, which greatly simplifies the process.
    1. Now this is where the magic of our activestorage library from node package manager comes in. At the top of our CreateAccount.js file we need to import a Component, DirectUpload, from this library…
    1. I ran into the same problem and never really found a good answer via the test objects. The only solution I saw was to actually update the session via a controller. I defined a new action in one of my controllers from within test_helper (so the action does not exist when actually runnning the application). I also had to create an entry in routes. Maybe there’s a better way to update routes while testing. So from my integration test I can do the following and verfiy: assert(session[:fake].nil?, “starts empty”) v = ‘Yuck’ get ‘/user_session’, :fake => v assert_equal(v, session[:fake], “value was set”)
    2. I find the use of the term “session” within integration tests a bit unfortunate (open_session, etc), since there are also these session objects, which are however different. Maybe replace by “user_session” ?
    1. TL;DR For classic Rails apps we have a built-in scope for preloading attachments (e.g. User.with_attached_avatar) or can generate the scope ourselves knowing the way Active Storage names internal associations.GraphQL makes preloading data a little bit trickier—we don’t know beforehand which data is needed by the client and cannot just add with_attached_<smth> to every Active Record collection (‘cause that would add an additional overhead when we don’t need this data).That’s why classic preloading approaches (includes, eager_load, etc.) are not very helpful for building GraphQL APIs. Instead, most of the applications use the batch loading technique.
    1. To upload a file, a client must perform the following steps:Obtain the file metadata (filename, size, content type and checksum)Request direct upload credentials and a blob ID via API—createDirectUpload mutationUpload the file using the credentials (no GraphQL involved, HTTP PUT request).