Close Menu
    DevStackTipsDevStackTips
    • Home
    • News & Updates
      1. Tech & Work
      2. View All

      Sunshine And March Vibes (2025 Wallpapers Edition)

      May 31, 2025

      The Case For Minimal WordPress Setups: A Contrarian View On Theme Frameworks

      May 31, 2025

      How To Fix Largest Contentful Paint Issues With Subpart Analysis

      May 31, 2025

      How To Prevent WordPress SQL Injection Attacks

      May 31, 2025

      Windows 11 version 25H2: Everything you need to know about Microsoft’s next OS release

      May 31, 2025

      Elden Ring Nightreign already has a duos Seamless Co-op mod from the creator of the beloved original, and it’ll be “expanded on in the future”

      May 31, 2025

      I love Elden Ring Nightreign’s weirdest boss — he bargains with you, heals you, and throws tantrums if you ruin his meditation

      May 31, 2025

      How to install SteamOS on ROG Ally and Legion Go Windows gaming handhelds

      May 31, 2025
    • Development
      1. Algorithms & Data Structures
      2. Artificial Intelligence
      3. Back-End Development
      4. Databases
      5. Front-End Development
      6. Libraries & Frameworks
      7. Machine Learning
      8. Security
      9. Software Engineering
      10. Tools & IDEs
      11. Web Design
      12. Web Development
      13. Web Security
      14. Programming Languages
        • PHP
        • JavaScript
      Featured

      Oracle Fusion new Product Management Landing Page and AI (25B)

      May 31, 2025
      Recent

      Oracle Fusion new Product Management Landing Page and AI (25B)

      May 31, 2025

      Filament Is Now Running Natively on Mobile

      May 31, 2025

      How Remix is shaking things up

      May 30, 2025
    • Operating Systems
      1. Windows
      2. Linux
      3. macOS
      Featured

      Windows 11 version 25H2: Everything you need to know about Microsoft’s next OS release

      May 31, 2025
      Recent

      Windows 11 version 25H2: Everything you need to know about Microsoft’s next OS release

      May 31, 2025

      Elden Ring Nightreign already has a duos Seamless Co-op mod from the creator of the beloved original, and it’ll be “expanded on in the future”

      May 31, 2025

      I love Elden Ring Nightreign’s weirdest boss — he bargains with you, heals you, and throws tantrums if you ruin his meditation

      May 31, 2025
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»News & Updates»CodeSOD: Not Exactly Gems

    CodeSOD: Not Exactly Gems

    February 6, 2025

    Sammy‘s company “jumped on the Ruby on Rails bandwagon since there was one on which to jump”, and are still very much a Rails shop. The company has been around for thirty years, and in that time has seen plenty of ups and downs. During one of those “ups”, management decided they needed to scale up, both in terms of staffing and in terms of client base- so they hired an offshore team to promote international business and add to their staffing.

    A “down” followed not long after, and the offshore team was disbanded. So Sammy inherited the code.

    I know I’m generally negative on ORM systems, and that includes Rails, but I want to stress: they’re fine if you stay on the happy path. If your data access patterns are simple (which most applications are just basic CRUD!) there’s nothing wrong with using an ORM. But if you’re doing that, you need to use the ORM. Which is not what the offshore team did. For example:

    class Request < ActiveRecord::Base
      def self.get_this_years_request_ids(facility_id)  # There are several other methods that are *exactly* the same, except for the year
    
          requests = Request.where("requests.id in (select t.id from requests as t                    # what is the purpose of this subquery?
                  where t.unit_id=token_requests.unit_id and t.facility_id=token_requests.facility_id
                  and t.survey_type = '#{TokenRequest::SURVEY_TYPE}'                                  # why is SURVEY_TYPE a constant?
                  and EXTRACT( YEAR FROM created_at) = EXTRACT(YEAR FROM current_timestamp)          
                     order by t.id desc) and token_requests.facility_id = #{facility_id.to_i}         # so we get all the requests by year, then by by ???
                     and token_requests.survey_type = '#{Request::SURVEY_TYPE}'")               
    

    Comments from Sammy.

    Now, if we just look at the signature of the method, it seems like this should be a pretty straightforward query: get all of the request IDs for a given facility ID, within a certain time range.

    And Sammy has helpfully provided a version of this code which does the same thing, but in a more “using the tools correctly” way:

    def self.request_ids_for_year(facility_id,year = Time.now.year)
       
        token_requests = TokenRequest.where(
                                  :facility_id=>facility_id,
                                  :survey_type=>TokenRequest::SURVEY_TYPE,
                                  :created_at=>(DateTime.new(year.to_i).beginning_of_year .. DateTime.new(year.to_i).end_of_year))
    

    Now, I don’t know Ruby well enough to be sure, but the DateTime.new(year.to_i) whiffs a bit of some clumsy date handling, but that may be a perfectly cromulent idiom in Ruby. But this code is pretty clear about what it’s doing: finding request objects for a given facility within a given year. Why one uses Request and the other uses TokenRequest is a mystery to me- I’ m going to suspect some bad normalization in the database or errors in how Sammy anonymized the code. That’s neither here nor there.

    Once we’ve gotten our list of requests, we need to process them to output them. Here’s how the offshore code converted the list into a comma delimited string, wrapped in parentheses.

    	string_token_request_ids = "(-1)"
        if token_requests && token_requests.length > 0
          for token_request in token_requests
            if string_token_request_ids != ""
              string_token_request_ids = string_token_request_ids + ","
            end
            string_token_request_ids = string_token_request_ids + token_request.id.to_s
          end
            string_token_request_ids = "(" + string_token_request_ids + ")"
        end
      end
    end
    

    Look, if the problem is to “join a string with delimiters” and you write code that looks like this, just delete your hard drive and start over. You need extra help.

    We start by defaulting to (-1) which is presumably a “no results” indicator. But if we have results, we’ll iterate across those results. If our result string is non-empty (which it definitely is non-empty), we append a comma (giving us (-1),). Then we append the current token ID, giving us (-1),5, for example. Once we’ve exhausted all the returned IDs, we wrap the whole thing in parentheses.

    So, this code is wrong– it’s only supposed to return (-1) when there are no results, but as written, it embeds that in the results. Presumably the consuming code is able to handle that error gracefully, since the entire project works.

    Sammy provides us a more idiomatic (and readable) version of the code which also works correctly:

        return "(#{token_requests.count > 0 ? token_requests.map(&:id).join(',') : '(-1)'})"
    

    I’ll be honest, I hate the fact that this is returning a stringly-typed list of integers, but since I don’t know the context, I’ll let that slide. At the very least, this is a better example of what joining a list of values into a string should look like.

    Sammy writes:

    It seems these devs never took the time to learn the language. After asking around a bit, I found out they all came from a Java background. Most of this code seems to be from a VB playbook, though.

    That’s a huge and undeserved insult to Visual Basic programmers, Sammy. Even they’re not that bad.

    [Advertisement]
    Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!

    Source: Read More 

    Hostinger
    Facebook Twitter Reddit Email Copy Link
    Previous ArticleFOSS Weekly #25.06: Linux inside PDF file, Missing Windows from Grub, GTK Drops X11 and More
    Next Article ONLYOFFICE Docs 8.3 released: stamps and multi-page selection in PDF files, enhanced collaboration in sheets, Shape Merge and more

    Related Posts

    News & Updates

    Windows 11 version 25H2: Everything you need to know about Microsoft’s next OS release

    May 31, 2025
    News & Updates

    Elden Ring Nightreign already has a duos Seamless Co-op mod from the creator of the beloved original, and it’ll be “expanded on in the future”

    May 31, 2025
    Leave A Reply Cancel Reply

    Continue Reading

    Community managers in action: Leading a developer community for good

    News & Updates

    Acquia Cloud Site Review – A Crucial Step for Success

    Development

    Simplest, dumbest reason your meetings suck

    Web Development

    DevHome.PI.exe: What is it & Can I Remove it?

    Development

    Highlights

    Understanding the faulty proteins linked to cancer and autism

    May 13, 2025

    Helping uncover how protein mutations cause diseases and disorders Source: Read More 

    RED ALERT: For 11 hours, HP has an Intel laptop with 32GB of RAM for $495, which is $2,000 off its regular price 🫨 (Updated!)

    December 1, 2024

    FOSS Weekly #24.50: Beautiful Distros, Open Source for Windows, Thunar Tweaks, Hyprpaper and More

    December 12, 2024

    Community News: Latest PEAR Releases (03.10.2025)

    April 15, 2025
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

    Type above and press Enter to search. Press Esc to cancel.