Skip to content
This repository was archived by the owner on Oct 19, 2018. It is now read-only.
This repository was archived by the owner on Oct 19, 2018. It is now read-only.

Access Rails route helpers from Hyperloop #228

Closed
@sfcgeorge

Description

@sfcgeorge

The ideal would be to access Rails route helpers verbatim just as you would in backend views or helpers. But the routing code is pretty tangled so I think it won't be possible to run it directly on the frontend without effort.

A workaround is to add .erb to component files and interpolate the route on the backend with static placeholder values, then gsub in real values on the frontend.

First, make it easier to access route helpers:

# config/initializers/routes.rb
class Routes
  include Singleton
  include Rails.application.routes.url_helpers

  def self.method_missing(name, *args, &block)
    if instance.respond_to?(name)
      instance.send(name, *args, &block)
    else
      super
    end
  end

  def self.respond_to_missing?(name, include_all = false)
    instance.respond_to?(name, include_all)
  end
end

Then in your ApplicationComponent add this helper to do the substitution:

class ApplicationComponent < Hyperloop::Component
  def rails_route(route, *positional, **named)
    route = route.split("/").reverse.join("/")
    positional.each_with_index do |replacement, i|
      route = route.sub(i.to_s, replacement.to_s)
    end
    named.each do |key, replacement|
      route = route.sub(key.to_s, replacement.to_s)
    end
    "/" + route.split("/").reverse.join("/")
  end
end

And finally use the mechanism in your components:

class CommentLink < ApplicationComponent
  param :comment

  render do
    A(href: rails_route(
      "<%= Routes.user_posts_comments_path(0, 1, "xyz") %>", 
      User.current.id, params.comment.post.id, xyz: params.comment.id
    )) { "View Comment" }
  end
end

Using positional arguments is the easiest, but if your route contains numbers it won't work so explicitly name your arguments with placeholders that won't clash. The above example shows both.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions