Rails 7 allows anything that responds to `#to_str` into redirect_to


Rails 7 adds support for passing all string-like arguments (that respond_to? #to_str) to redirect_to.

Any class that defines #to_str like the Addressable::URI class can now be passed to redirect_to.

We can also write a custom class that defines #to_str as shown below.

Example

  class GoogleSearcher
    attr_reader :query

    def initialize(query)
      @query = query
    end

    def to_str
      "https://www.google.com/search?q=#{query}"
    end
  end

Before

  def saeloun_home
    redirect_to "https://saeloun.com"
  end
  #=> No error, will work properly and redirect us to https://saeloun.com

  def google_home
    redirect_to Addressable::URI.parse("https://google.com")
  end
  #=> Raises NoMethodError

  def search
    redirect_to GoogleSearcher.new("Cat Pics")
  end
  #=> Raises NoMethodError

In the above example, the google_home action will raise a NoMethodError as redirect_to expects a string argument. (Or a Hash, a Record or a block that gets evaluated to a string)

Similarly, the search action will raise a NoMethodError for the user-defined class.

After

  def saeloun_home
    redirect_to "https://saeloun.com"
  end
  #=> No error raised

  def google_home
    redirect_to Addressable::URI.parse("https://google.com")
  end
  #=> No error raised

  def search
    redirect_to GoogleSearcher.new("Cat Pics")
  end
  #=> No error raised

In the above example, for the google_home action, #to_str gets internally called on Addressable::URI.parse("https://google.com").

A valid string URL is returned and, we are successfully redirected to https://google.com.

Similarly, for the search action, #to_str gets internally called on the GoogleSearcher class object and we are successfully redirected to https://www.google.com/search?q=Cat%20Pics.