Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix titles in breadcrumbs (particularly belongs_to) #2601

Merged
merged 1 commit into from
Nov 11, 2013

Conversation

shekibobo
Copy link
Contributor

Fixes #2132. For realz.

@shekibobo
Copy link
Contributor Author

module ActiveAdmin
  module ViewHelpers
    module BreadcrumbHelper

      # Returns an array of links to use in a breadcrumb
      def breadcrumb_links(path = request.path)
        parts = path[1..-1].split('/') # remove leading "/" and split up the URL
        parts.pop                      # remove last since it's used as the page title

        parts.each_with_index.map do |part, index|
          # 1. try using `display_name` if we can locate a DB object
          # 2. try using the model name translation
          # 3. default to calling `titlecase` on the URL fragment
          if part =~ /\A(\d+|[a-f0-9]{24})\z/ && parts[index-1]

I'm confused about what's happening here. If we grab the belongs_to_config (if it exists), aren't we always going to get the parent resource? It seems like just grabbing active_admin_config would do what we want, but that's coming from the controller as far as I can tell.

            config = active_admin_config.belongs_to_config.try(:target) || active_admin_config
            name   = display_name config.find_resource(part)
          end
          name ||= I18n.t "activerecord.models.#{part.singularize}", :count => 1.1, :default => part.titlecase

          link_to name, '/' + parts[0..index].join('/')
        end
      end

    end
  end
end

@shekibobo
Copy link
Contributor Author

Is there a way to check if the parts[index-1] string in some way matches the config we get?

@zorab47
Copy link
Contributor

zorab47 commented Oct 22, 2013

You may be able to compare it to the routes defined in resource/routes.rb, if it is a resource config object.

@shekibobo
Copy link
Contributor Author

I've got this tested manually and it appears to work, but I can't get the specs to pass. I'm pretty new to using test doubles, and here's the error I get:

Failure/Error: let(:trail) { breadcrumb_links(path) }
       Double received unexpected message :find_resource with ("1")
     # ./lib/active_admin/view_helpers/breadcrumb_helper.rb:19:in `block in breadcrumb_links'
     # ./lib/active_admin/view_helpers/breadcrumb_helper.rb:10:in `each'
     # ./lib/active_admin/view_helpers/breadcrumb_helper.rb:10:in `each_with_index'
     # ./lib/active_admin/view_helpers/breadcrumb_helper.rb:10:in `each'
     # ./lib/active_admin/view_helpers/breadcrumb_helper.rb:10:in `map'
     # ./lib/active_admin/view_helpers/breadcrumb_helper.rb:10:in `breadcrumb_links'
     # ./spec/unit/view_helpers/breadcrumbs_spec.rb:26:in `block (3 levels) in <top (required)>'
     # ./spec/unit/view_helpers/breadcrumbs_spec.rb:172:in `block (4 levels) in <top (required)>'

It's the same for each test lines 157-176.

@zorab47
Copy link
Contributor

zorab47 commented Oct 27, 2013

That error is being raised because the active admin config double does not respond to the #find_resource method.

FYI, naming doubles is helpful in finding these types of errors:

double("user", display_name: "User 1")

@zorab47
Copy link
Contributor

zorab47 commented Oct 27, 2013

I think the intent is for the active_admin_config to be an alias of post_config.

With this change all the tests pass:

let :active_admin_config do
  post_config
end

@shekibobo
Copy link
Contributor Author

Thanks @zorab47, that seems to have fixed it.

if part =~ /\A(\d+|[a-f0-9]{24})\z/ && parts[index-1]
config = active_admin_config.belongs_to_config.try(:target) || active_admin_config
name = display_name config.find_resource(part)
if part =~ /\A(\d+|[a-f0-9]{24})\z/ && route_key = parts[index-1]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line has become very complex. How would you describe its purpose and can it be factored out into a predicate method?

Is it checking for parent components of the URL?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically, if part is an id-like parameter, and the previous part exists (if so, it is the route key), then we have a chain we can use to figure out what the resource is.

I could just as easily not do the assignment in the conditional, changing it to

if part =~ /\A(\d+|[a-f0-9]{24})\z/ && parts[index-1]
  route_key = parts[index-1]
  # ...

or

config   = parent_config if parent_config && parent_config.resource_name.route_key == parts[index-1]

@seanlinsley
Copy link
Contributor

There's a lot of lines changed in the tests, particularly switching from posts to users. What do those changes accomplish?

@shekibobo
Copy link
Contributor Author

Mostly keeps the test running down the same chain of associations. Before the tests were only checking for the first set of associations in the breadcrumbs. The new ones assume that a chain like admin/users/1/posts/1/edit. I changed the tests to have a consistent context throughout. Before, it was just looking at posts, but I needed posts to belong to users. Since the resource itself is arbitrary for top-level routes, I switched it to users so posts could show up nested.

@jerodsanto
Copy link

Just want to add my +1 to this PR. I kept getting a nil resource when using belongs_to on an edit action and pulling in @shekibobo's changes fixed it for me.

I also agree that the if part line is quite complex and could use a little refactoring, but would like to see this merged regardless.

Thanks to all for your hard work!

@seanlinsley
Copy link
Contributor

Anything need changing in this PR @shekibobo?

@shekibobo
Copy link
Contributor Author

Well, I could move the variable assignment out of that first line, but aside from that coding style issue and a squash, I'm good to go on this one.

@seanlinsley
Copy link
Contributor

I was considering changing it to:

if part =~ /\A(\d+|[a-f0-9]{24})\z/ && parts[index-1]
  parent = active_admin_config.belongs_to_config.try :target
  config = parent && parent.resource_name.route_key == parts[index-1] ? parent : active_admin_config
  name   = display_name config.find_resource part
end

But then you have one really long line in the middle :/

@shekibobo
Copy link
Contributor Author

That was kind of the struggle I was having. It's either multiple lines or longer lines. Not sure we can shortcut the logic anywhere, really. Either way should work, though. Your call.

@seanlinsley
Copy link
Contributor

Hmm, yeah let's go the longer line route. I think it more clearly describes what's happening, even if style guides might frown on it.

@shekibobo
Copy link
Contributor Author

Travis sent me an email saying the build was broken before they all passed, so I rebased on master to be sure. If it passes, I'll squash and we should be good to go.

@shekibobo
Copy link
Contributor Author

Squashed 💚

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.03%) when pulling 59fea68 on shekibobo:2132-fix-breadcrumbs into dea86ac on gregbell:master.

seanlinsley added a commit that referenced this pull request Nov 11, 2013
Fix titles in breadcrumbs (particularly belongs_to)
@seanlinsley seanlinsley merged commit b6db2d4 into activeadmin:master Nov 11, 2013
tagliala added a commit to tagliala/activeadmin that referenced this pull request Apr 30, 2024
Found with `codespell`

The typo was there before activeadmin#2601, but according to activeadmin#2601 the intent is
to test `/posts/1` and not `comments` anymore
tagliala added a commit to tagliala/activeadmin that referenced this pull request May 1, 2024
Found with `codespell`

The typo was there before activeadmin#2601, but according to activeadmin#2601 the intent is
to test `/posts/1` and not `comments` anymore
tagliala added a commit that referenced this pull request May 1, 2024
Found with `codespell`

The typo was there before #2601, but according to #2601 the intent is
to test `/posts/1` and not `comments` anymore
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Incorrect title displayed in edit breadcrumbs
5 participants