Updates from July, 2021 Toggle Comment Threads | Keyboard Shortcuts

  • ThomasPowell 7:34 am on July 13, 2021 Permalink | Reply
    Tags: factory_bot, factory_girl, , , , trait   

    Referencing one trait from another trait in factory_bot 

    Sometimes you want to DRY up traits by referencing one trait from another trait in factory_bot. I tried searching on “inheriting traits” (that’s just for one factory inheriting traits from another and was in a factory_bot issue in GitHub). I accidentally stumbled upon the answer in a slightly unrelated StackOverflow question about calling a trait from another trait with params in factory_girl.

    Ultimately, you use the trait name from the first trait as a method invocation in the referencing trait:

    FactoryBot.define do
      factory :user do
        trait :with_supervisor do
          # complex set up might go
          # here
          after(:create) do |user|
            supervisor { create(:user) }
        trait :with_organization do
          with_supervisor # invoke the other trait first
  • ThomasPowell 8:48 pm on July 6, 2021 Permalink | Reply
    Tags: ,   

    RAW_POST_DATA in rspec rails for Rails 5.2 and beyond 

    The last time I was trying to specify RAW_POST_DATA in rspec was probably Rails 3 or 4, but I ran into a situation trying to test an edge case for error handling where I wanted that same functionality. I quickly found this issue [Unable to POST raw request body], but didn’t immediately figure out what wasn’t being set correctly.

    In this case the test setup I was using was setting multipart/form-data instead of application/xml on the content types:

    {:HTTP_ACCEPT=>"application/xml", :HTTP_CONTENT_TYPE=>"multipart/form-data", :CONTENT_TYPE=>"multipart/form-data"}

    Because of this, the Rails controller tests that rspec hooks into was trying to break following malformed xml down to parameters:

       Expected response to be a <400: bad_request>, but was a <422: Unprocessable Entity>
       Response body: <errors>
           <error>["<test>\n  <data", "nbsp;\n  <!"] are not permitted parameters</error>

    I finally noticed that the mime-type might be involved. In this code, Content-Type was also an issue, so:

    • Removed HTTP_CONTENT_TYPE from the headers
    • Set CONTENT_TYPE header to 'application/xml' instead of 'multipart/form-data' to prevent automatic params parsing in this case.
    • Passed as: :xml into the test to get the 'mime-type' correct.

    Ultimately, if your code hasn’t boxed you in, then the as: :xml and passing raw data as a parameter should work:

    post things_path, params: raw_xml_data, headers: non_form_data_headers, as: :xml
    ## replacement for the following:
    # @request.env['RAW_POST_DATA'] = raw_xml_data
    # post things_path
  • ThomasPowell 9:18 pm on July 5, 2021 Permalink | Reply
    Tags: , , tr, translate   

    String#tr in ruby (like tr in Linux) complete with figuring out slashes. 

    It seems like I’ve seen quite a few programming puzzles in the last few weeks that involved translating mistyped input in which the hands were shifted (right) on the keyboard. My first thought was the tr utility in *nix operating systems, but didn’t immediately go looking for or notice that ruby has a tr method on string. However, after doing a trivial implementation involving keyboard rows like the following, I stumbled on the tr method.

      # initial array of characters/strings to shift back to the left with [index-1]
        'qwertyuiop[]\\', # need to escape the backslash or else debugging pain
        "asdfghjkl;'", # double-quotes here because single quote embedded
        '[email protected]#\$%^&*()_+',

    Attempting to rewrite this for .tr presented a few challenges, however. If you are substituting for \, -, or ~, you have to escape the characters. You also have to escape them from their string representation, which makes for some head-spinning levels of escaping (zsh users who run shell commands through kubectl might be familiar with this pain as well):

    # puts '\\~-'.tr('\\', 'a') # doesn't match because \ is passed to tr and not escaped
    # puts '\\~-'.tr('\\\\', 'a') # now \\ is passed to tr, which is
    # puts '\\~-'.tr("\\\\\\", 'a') # with double quotes, you need an extra pair, for 6 total.
    # puts '\\~-'.tr('\\~', 'b') # the escaping backslash needs to be doubled
    # puts '\\~-'.tr("\\\~", 'b') # the escaping backslash needs to be tripled
    # puts '\\~-'.tr('\\-', 'c') # the escaping backslash needs to be doubled
    # puts '\\~-'.tr("\\\-", 'c') # the escaping backslash needs to be tripled

    So if you’re going to use translate to “shift” hands back to the left, the two arguments to tr, SHIFTED_KEYBOARD_ROWS and UNSHIFTED_KEYBOARD_ROWS would have to be defined with the following escaping:

          'wertyuiop[]\\\\', # 4x backslash = backslash
          '[email protected]#\$%\^&*()_+',
        'qwertyuiop[]', # need to escape the backslash or else debugging pain
        '[email protected]#\$%\^&*()_',
      def self.translate(string)
Compose new post
Next post/Next comment
Previous post/Previous comment
Show/Hide comments
Go to top
Go to login
Show/Hide help
shift + esc
%d bloggers like this: