bullet-train-co / bullet_train-super_scaffolding

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Rethink how we check for namespaced `has_many` class names

gazayas opened this issue · comments

I've been looking into these TODOs from the Transformer, and on the surface they didn't seem too difficult, but the issue is definitely more complicated than first expected:

# TODO I _think_ this is the right way to check for whether we need `class_name` to specify the name of the model.
unless transform_string("completely_concrete_tangible_things").classify == child
  has_many_line << "class_name: \"Scaffolding::CompletelyConcrete::TangibleThing\""
end

has_many_line << "dependent: :destroy"

# TODO I _think_ this is the right way to check for whether we need `foreign_key` to specify the name of the model.
unless transform_string("absolutely_abstract_creative_concept_id") == "#{parent.underscore}_id"
  has_many_line << "foreign_key: :absolutely_abstract_creative_concept_id"

  # And if we need `foreign_key`, we should also specify `inverse_of`.
  has_many_line << "inverse_of: :absolutely_abstract_creative_concept"
end

The problem

The first block runs when Super Scaffolding Projects::Deliverable within bundle exec test/bin/setup-super-scaffolding-system-test. Here's the output we get when checking for the transformed string

pry(#<Scaffolding::Transformer>)> transform_string("completely_concrete_tangible_things")
=> "deliverables"

child is Project::Deliverables though, so although we should be getting projects_deliverables, we get deliverables so it's cutting off the namespace and will always add the class_name option. It's technically adding it to the right place, but the check isn't entirely accurate.

Somewhat close solution

I ended up using the following:

[1] pry(#<Scaffolding::Transformer>)> child
=> "Projects::Deliverable"
[2] pry(#<Scaffolding::Transformer>)> parent
=> "Project"
[3] pry(#<Scaffolding::Transformer>)> transform_string("scaffolding_completely_concrete_tangible_things")
=> "projects_deliverables"

However, when classfying it, we just get this:

ProjectsDeliverable

We could somehow use a regexp to insert :: in the proper places, but I feel like this still doesn't cover the core issue. I know we call class_name when the database table has a different name than what we're working with, but I'm having trouble trying to flesh out what would be a good model setup to make sure this part runs as desired.

Questions

  1. What's an example model design we can refer to when working with this logic? In other words, what rails g model/Super Scaffolding combination is the most ideal to check this part of the code?
  2. Do we want to skip namespaced models? Would it just be common sense that the database table would carry the same name as the child given in the Transformer?

Final thoughts

Our Super Scaffolding system tests have been working up until now with these unless statements, but it would definitely be better to have a firm grasp on this part in case we run into any related problems in the future.

Still, it's not an easy one so I think it'll take me some time to work on it.

Although the main Super Scaffolding system test isn't failing, I noticed this output from the setup script and it seems to be related to the files we're trying to adjust around the TODOs in this issue:

Couldn't find 'app/views/account/deliverables/index.json.jbuilder'
Couldn't find 'app/views/account/deliverables/show.json.jbuilder'
Couldn't find 'app/views/account/deliverables/index.json.jbuilder'
Couldn't find 'app/views/account/deliverables/show.json.jbuilder'

I was just trying to resolve these earlier today, and found that using the following at the beginning of the transform_string method retrieved the proper string:

path_without_scaffolding_hook = "account/completely_concrete/tangible_things"
path_with_scaffolding_hook = "account/scaffolding/completely_concrete/tangible_things"
string = string.gsub(path_without_scaffolding_hook, path_with_scaffolding_hook)

Still a little confused on this one, but I just thought this was significant enough to comment on.

I had this one logged away in my notes as unfinished and it was bothering me for a bit, but looking back on this one, I see that I had already taken care of it.