0

I am trying to perform the following actions to alter my urls:

  1. parse instances of "an-" from my url
  2. remove a prefix of "the-" from my url if present.
class BlogPost < ApplicationRecord
  extend FriendlyId
  friendly_id :custom_slug, use: :history

  ...

  def custom_slug
    a = "#{title.to_s}"

    # goal is to remove the following words from url: an
    # the word being removed goes after "/\b and before \b/"
    # "#{title}".gsub! "/\ban\b/", ""
    a.gsub! "/\ban-\b/", ""

    # this should remove "the-" from the beginning of a slug if it's there
    if a.start_with?("the-")
      a.slice! "the-"
    end

    return a
  end

end

A title I'm trying to alter is "the example of an the post"

friendly_id converts to: /the-example-of-an-the-post

I want: /example-of-the-post

But my code to do this is not being executed and is just returning the original string. I know the .slice! portion of my code should work but I don't actually know if my code is correct or effective in this application of it.


Update

Following advice from @Schwern I came to some other conclusions to fix my issue:

a = "#{title.to_s}" to a = "#{title.to_s.downcase}"

Replaced faulty REGEX with a simpler solution:

if a.include?(" an ")
  a.gsub! " an ", " "
end

And directly from Schwern I was targeting something in the :slug and not the :title so it just had to change to this:

if a.start_with?("the ")
  a.slice! "the "
end
Jake
  • 1,086
  • 12
  • 38
  • Do you have `include FriendlyId` in your ApplicationRecord? Did you try extracting the function and testing it on its own? How do you know the method is not being called? – Schwern Feb 25 '23 at 21:00
  • 1
    What is in `title`? Are you sure it's `the-example-of-an-the-post` and not `The example of an the post`? – Schwern Feb 25 '23 at 21:03
  • @Schwern I have `extend FriendlyId`. I updated my question to include that. – Jake Feb 25 '23 at 22:00
  • 1
    Note that you can just write `a = title.downcase`. Glad you got it figured out. – Schwern Feb 25 '23 at 23:00
  • Thank you for that! It's much cleaner and I didn't know the `.downcase` method stringified too. – Jake Feb 25 '23 at 23:55
  • 1
    It doesn't, `title` is (presumably) already a String. You couldn't call downcase on it if it wasn't. If you do need to stringify, use just `.to_s`, no quotes. `"#{var}"` implicitly stringifies, and you should only use it if you're building a new string. `"The title is #{title}"`. Try rubocop and rubocop-rails to audit your code and learn more best practices. Some are pretty arbitrary, but most are useful. Good luck! – Schwern Feb 26 '23 at 00:00

2 Answers2

1

Some tips

# a = "#{title.to_s.downcase}"
# No need for interpolation inside "#{}".
# If the title always returns a string, you don't need to_s.
# Add to_s only if there is a possibility of returning nil.
# It is also good to better name the variable
new_slug = title.downcase

new_slug.gsub!(" an ", " ") if new_slug.include?(" an ")
new_slug.slice!("the ") if new_slug.start_with?("the ")

# Don't need the return statement on the last line
new_slug
0

You're matching against the title of the post. Presumably the post is not titled the-example-of-an-the-post, that is how it would appear after conversion to a URL. The title is likely The example of an the post.

Schwern
  • 153,029
  • 25
  • 195
  • 336