bullet-train-pro / bullet_train-action_models

Other
5 stars 1 forks source link

Target one Action Models don't have correct path to new action #14

Open gazayas opened 2 years ago

gazayas commented 2 years ago

Context: https://discord.com/channels/836637622432170028/836637623048601633/1030327785492860960

For example:

> rails g model Email team:references subject:string
> bin/super-scaffold crud Email Team subject:text_field
> bin/super-scaffold action-model:targets-one Test Email Team

We get the following line in app/views/accounts/emails/test_actions/_new_button_one.html.erb:

<% if can? :create, Emails::TestAction.new(email: email) %>
  <%= link_to t('emails/test_actions.buttons.shorthand.create'), [:new, :account, email, :test_action], class: 'button-secondary button-smaller bulk-action-single button_to' %>
<% end %>

I'm not sure how we should change [:new, :account, email, :test_action], but this is the path that doesn't exist and is giving us an error.

For reference, we get the following when super scaffolding a targets-many action model:

[:new, :account, team, :emails_test_action, emails_test_action: {target_ids: [email.id]}]
andrewculver commented 2 years ago

I wonder if this is a problem in the routes generation? Is it not generating the route correctly?

jot commented 2 years ago

My solution was to use the equivalent of the following in generated links and forms:

[:new, :account, email, :emails, :test_action]

My routes ended up looking like this (not sure if it's different from generated):

        resources :emails do
          namespace :emails do
            resources :test_actions
          end
        end
andrewculver commented 2 years ago

Oof, yes, you don't want that redundant email, :emails... if that works, it means we didn't generate the routes correctly.

andrewculver commented 2 years ago

@jot Routes generation and manipulation is one of the most complicated things we do in Bullet Train. It might take a bit to resolve this. In the meantime, you should probably undo whatever routes are incorrectly generated and figure out how to write them yourself using the guidance at https://blog.bullettrain.co/nested-namespaced-rails-routing-examples/ . You'll know you've got them right when the path helpers stop throwing an error.

jot commented 2 years ago

I reverted my changes to the path helpers.

It's now working with the following routes:

        resources :emails do
          scope module: 'emails' do
            resources : test_actions
          end
        end

        namespace :emails do
          resources : test_actions
        end
gazayas commented 1 year ago

It looks like bullet_train-super_scaffolding itself wasn't broken, but the value we were setting as the parent when initializing the RoutesFileManipulator object in the transformer was the culprit. The original value we had worked fine for the targets-many action, but I had to change it for the targets-one action. I changed it to the following, which you can find in #19:

parent = targets_n == "targets-one" ?
  transform_string("Scaffolding::CompletelyConcrete::TangibleThing") : transform_string("Scaffolding::AbsolutelyAbstract::CreativeConcept")

routes_manipulator = Scaffolding::RoutesFileManipulator.new(
  details[:file_name],
  transform_string("Scaffolding::CompletelyConcrete::TangibleThings::#{targets_n.classify}Action"),
  parent
)

If we use Email and a Test action as an example, we would Super Scaffold it like this:

> bin/super-scaffold action-model:targets-one Test Email Team

Before, the last argument for the initializer was this, which was causing us to set Team as the parent:

transform_string("Scaffolding::AbsolutelyAbstract::CreativeConcept")

We want Email though with test_actions scaffolded under the proper resources and namespace blocks, so by defining parent dynamically, we set it to Email resulting in the proper routes.