Finding the class based on an object instance of the object in Rails with Constantize

Trying to write a rails method to count the rows in a table.

The twist:  I want to do it in such a way that I can call the method from any object and it will automatically determine the name of the table to count the rows from.

Basic outline of the flow … I want to use Rails Way to identify the table & count the resulting table name’s rows.

Model.count

To do so I need the name of the model.  As my test object, I cleverly naming it anObject

2.3.1 :040 > anObject = Player.first
 Player Load (2.4ms) SELECT "players".* FROM "players" ORDER BY "players"."id" ASC LIMIT $1 [["LIMIT", 1]]
 => #<Player id: 1, screenname: "Serena Mitchell I", motto: "Wyaaaaaa.", country_id: nil, created_at: "2017-09-01 12:52:27", updated_at: "2017-09-01 12:52:27">

Rails has several definitions which hold that information in various states.  I chose to use .class …

2.3.1 :043 > anObject.class
 => Player(id: integer, screenname: string, motto: string, country_id: integer, created_at: datetime, updated_at: datetime)

When we look at this, it’s more information than we need.    The Rails Way is to call the .name method out of the class method …

2.3.1 :046 > anObject.class.name
 => "Player"

As a bonus .name gives us access to .constantize which is the goal.

2.3.1 :048 > anObject.class.name.constantize
 => Player(id: integer, screenname: string, motto: string, country_id: integer, created_at: datetime, updated_at: datetime)

Now we can put .constantize to search all the Rails app’s constants …

2.3.1 :050 > anObject.class.name.constantize
 => Player(id: integer, screenname: string, motto: string, country_id: integer, created_at: datetime, updated_at: datetime)

… which when proceeded by the .class.name will give the activerecord model as an object which we can then .count against …

2.3.1 :052 > anObject.class.name.constantize.count
 (0.8ms) SELECT COUNT(*) FROM "players"
 => 46

At this point .class.name.constantize should net us what we need, so I wrap it in a method for easy reuse …

#  gets name of constant to get a count of model
def row_count(ar_object)
  ar_object.class.name.constantize.count
end

This of course isn’t perfect, if ever you had an conflict in the naming scheme, scope issues or an orphaned object from the inheritance tree, the .constantize search up the object inheritance tree would fail even though your object exists.

Note there is another way, that if you are only doing ActiveRecord objects works too … Link.  My example is slightly more generic example as you can use it to find other types of objectives – though you can’t use the count method with most of them.

The reason you would use it, is that it’s more self documenting, thus more in line with the Rails Way ….

# .model_name.name is basically the same as .class.name for this purpose
ar_object.model_name.name.constantize.count

My studies from other authors which I found helpful, in no particular order …

  • Failure points & discussions for constantize – Link
  • Implementing in a custom module from Stackoverflow – Link
  • Implementing the constantize lookup in depth & use – Link
  • Safelty constantize in forms, aka don’t – Link
  • Metaprogramming & testing with constantize – Link
Advertisements

Rails organization / patterns

Been summarizing some of my studies – note none of this is confirmed by an official Ruby on Rails historian …

I started out looking for where code was supposed to be placed.  Why?  Because I read about DRY.  I really liked the idea of not wasting time redoing code – it’s one of the reason I got into Rails, which I will call RoR from here forward.

So people divide the RoR apps up according to MVC philosophy, which the short version is the model of the database logic, the view you see & is’ logic, and the controller with its logic to tie the two together.

In this MVC design, when I entered RoR’s world most posters were talking about Fat Model / Skinny Controller.

I started reading a lot about this stuff … Justin Weiss has a great breakdown summary of different patterns & where they get placed in the RoR app – Link.  I also like the description of the process on Stackoverflow from ‘Jason‘ & Mike Woodhouse – Link.

 

From what I can gather from posts there was a development of programming as people moved along.  Notice I’m not numbering these…there’s a reason…

  • model / controller / views
  • helpers (with special visibility to only their views)
  • custom classes anywhere
  • app/lib as “the spot” which at one point in RoR history auto loaded (not anymore)
  • modules / mix-ins to include the classes/methods
  • gems – which
  • plugins – which were discontinued in Rails 4, but the command used to make engines now – Hawkins had a good break down if somewhat biased – Link
  • concerns – which even had a special activesupport::concerns for including classes added
  • rails engines which improve on the modules>gems by encapsulating the database too … often these are wrapped in gems when created with mountable option – this might be part of the micro-services movement…

The difference between a Jr & Senior programmer at Gitlabs

https://about.gitlab.com/jobs/build-engineer/

 

Junior Build Engineer

Junior Build Engineers are developers who meet the following criteria:

  1. Technical skills
    • Is able to write code in required languages but needs guidance in writing modular and maintainable code
    • Has less experience to no experience with containers
    • Proposes default configuration to reduce the need for configuration by customers
  2. Code quality
    • Leaves code in substantially better shape than before
    • Is able to write clear documentation
  3. Communication
    • Needs help with time management
    • Is able to follow technical conversations within the team
  4. Performance & Scalability
    • Needs help writing production-ready code
    • Has little to no experience writing large scale apps

Senior Build Engineer

Senior Build Engineers are experienced developers who meet the following criteria:

  1. Technical Skills
    • Are able to write modular, well-tested, and maintainable code
    • Know the domain really well and radiate that knowledge
    • Contribute to one or more complementary projects
  2. Leadership
    • Begins to show architectural perspective
    • Proposing new ideas, performing feasibility analyses and scoping the work
  3. Code quality
    • Leaves code in substantially better shape than before
    • Fixes bugs/regressions quickly
    • Monitors overall code quality
    • Reacts efficiently to build failures
    • Creates test plans
  4. Communication
    • Provides thorough and timely code feedback for peers
    • Able to communicate clearly on technical topics
    • Keeps issues up-to-date with progress
    • Helps guide other merge requests to completion
    • Is able to help with recruiting
  5. Performance & Scalability
    • Excellent at understanding the cost of a change
    • Excellent at writing production-ready code with little assistance
    • Able to write complex code that can scale with a significant number of users

Rails way? Rendering partials

Laying out some thoughts for myself here ...

So, I’ve been inserting partials for awhile …

At first I was sending only rails generated & cocoon gem partials.  Using the collections method I think.  :f => @controller_declared_model

When reading again from the rails guides – Link – I found you can feed in an array of values.  The documentation claims you can then render the layout of each with no effort.

I’m trying to find a way to feed a partial a controller declared dataset, which would allow me to create subsets of the Player.all & feed them in to be rendered.

Local or collection seems to be it … but I’m curious if these will still allow me to use the rails magic in links for editing/viewing etc.  More to follow when done testing.

Github’s extra features – issues versus projects – TDD/BDD

Trying to document a bit of what I am up too in the hopes it helps my workflow process improve.

Supposedly, when ADHD or tired this workflow will help you concentrate in order to be productive!

I’ve been hanging out on my github.com project lately.  Using the Issues List as my per task driver for the TDD/BDD stuff.  I’m actually listing out each command with a checkbox as my aid for doing & reversing the code I’m working with … usually the second time.  I also tried the “projects” thing off github’s repository … the feature is pretty meh for control though.  My frustration is that I can get check boxes and exacting lists of whatever length I want from the Issues list.

I really hate the idea of cluttering up my github issues list on projects which might get a volume of people (obviously my early stuff won’t suffer from this syndrome), so I’m attempting to shoe horn projects in to that role.  Currently, I’m using projects to describe the title of what I’m doing & Issue’s with check boxes the behavior that needs to be fixed along with the steps taken to fix the issue.

By no means am I an expert – more of a new guy imitating what I see other people doing.  So here’s my screen captures …

Version & date your guides – lol?

Let me preface this by stating, I’m grateful for any information on the internet.  I fully believe more is more.  For the context of this article – when beginning – you are looking for ways to judge if a guide/article will help you.  Some rather simple information at the beginning can prevent an article from wasting the time of a beginner.

Also, I’m a rank beginner when it comes to all of this …


I can follow tutorials.  When following tutorials there was usually 2 issues I had on a recurring basis…

  1. Out of date – this far and away would trip up everything
    1. Many tutorials didn’t have a front page detailing when they which versions they used.
    2. Sometimes the version gotcha’s was a note in the body of the instructions, buried pages in & effectively not there when you are just trying to decide if you should even bother reading it.
    3. Some tutorials did not even have a date on them or even a year
  2. Small errors and a beginners lack of knowledge to judge when the issue is bigger than a typo somewhere.
  3. Contextual issues.  When someone in their tutorial thought they clearly laid out or assumed everyone reading would automatically know something.  Mainly an issue if the guides didn’t include a “who’s this for” type front page disclaiming things.  Which platforms & addons/gems etc?

Now, how to better use your time …

Since I’m beginning to get more savvy to these types of things – I’m noticing not even the rails guide holds super easy documentation.  Googled me some rails guide for routing…one of first hits splashes me down here …

railsguide

The vaulted guide here does have documentation of the version number it works with ..  but the user has to know that they can click RailsGuides header/home & then they will get the information they need to see the version.  This page is one of the better of the examples – as the information is available – even if you have to hunt for it.  I feel like it looks simple & that was the purpose, which it accomplishes.

It is still missing the date of publication & updates that new changes or last minute things might cause new users pain.

My current rule when first googling away is that if I can’t find a version/date on the guide or article – it’s worthless to me.  When I get more desperate, and there is no good help – I will default to articles/guides with the date built into the URL, then default to articles which I can click somewhere to find notes/readme/help section – but no more than a mouse click away when scanning through articles.

If the author’s skill level is too low to explain the context or mention the version – they probably aren’t going to explain the topic well enough to be helpful to you anyways!