Removes the same top-level URL for organizations / users: domain.com/user and domain.com/organization work the same

I am trying to make the top level routing work with my Ember.js Rails API client in this way (similar to how GitHub works, for example):

Pressing www.example.com/username will give you a user page. This will either lead to the api.example.com/users/:username , or to some other endpoint.

Clicking www.example.com/organization_name will give you an organization page. This will result in either the api.example.com/organizations/:organization_name , or some other endpoint.

Upon receiving a random URL, the client obviously does not know which model it is dealing with. He will consider it as www.example.com/random_string , where random_string is either username or organization_name .

I'm not quite sure how to deal with this situation. It is not clear where the responsibility lies with the client or server here. I can imagine, maybe some kind of polymorphism works here, but cannot connect the dots.

EDIT

It seems like this is possible on the Rails side, having the entire route for /:slug , and then using slug for the first request for User , and then request for Organization .

Thus, a big question arises: does it make sense to process these requests by rendering with an existing controller action or allow HTTP to handle it using redirection. Will ember-data handle HTTP redirects correctly? And in another case, will he be able to switch types accordingly to this endpoint?

+7
ruby-on-rails
source share
3 answers

It seems like this is possible on the Rails side, having the entire route for // slug, and then using slug for the first request for the user, and then the request for the organization.

This is the only viable approach. You need to add this generic route at the very end of your config / routes.rb file. I advise you to associate this route with the proxy method in your controller, which will determine if the User or Organization slug entry matches.

Knowing that you must take into account the application when User and Organization have the same slug (some will prioritize one of them, some of them will provide the visitor with 2 options); and the action to be taken when the entry does not match slug (some of them will display 404, and some will go to the list page). These options will help you determine the best design for your proxy method.

The main thing here is to create this proxy method.

1- HTTP redirection

Your proxy method will respond redirect_to to / users /: slug or / organization /: slug depending on what is found in slug .

  • Advantage: easy and fast to write and maintain.
  • Disadvantage: slow application response due to HTTP redirection and the need to re-access the database during the second request.

2-Ajax answer

Similar to HTTP redirect, but performed in AJAX. Your proxy method will display a page containing JavaScript code that extracts the contents of / users /: slug or / organization /: slug and displays it through AJAX.

Alternatively, the URL can be changed using JavaScript using history.pushState

  • Advantage: a little faster than higher.
  • Disadvantage: but it’s more difficult to write, you need JavaScript code plus a js representation, and you still need to re-access the database during the second request.

3-server proxy

Your proxy method will execute the same code as your endpoint method. This means that if the slug found matches the User entry, the proxy method will do the same as UserController#show . (And the same goes for Organization )

This means that the proxy method should call all the filters before / after that UserController#show will be, and display the same view.

Be very careful if you choose this solution for DRY. Or you may have difficulty maintaining your application.

There is not a single method for this, and it all depends on the architecture of your application. If, for example, your show method simply retrieves the record and renders the view, and if there are no controller methods, then this is easy and safe. On the other hand, if you have filters and methods for controller assistants, then this gets a little more complicated. In this case, you can rely on problems with the controller.

  • Benefit: Quick Solution
  • Disadvantage: it can be very difficult to write, and depending on the evolution of your code base in the future, you may find yourself in a blocking situation when you have to abandon this development.
+3
source share

Create model

Create a new route model, it will belong to the user or organization. Give it a unique line and let it decide who it belongs to:

On the model:

 def owner self.organization || self.user end 

About organization and user:

 has_one :route_name before_create :create_route def create_route self.create_route_name(path: self.path) #change this to what ever the user wants end 

Then you can do:

 RouteName.find_by(name: "blah_blah").owner 
+3
source share

Inheritance of individual tables

Say we have a user and an organization, we can do the following:

 class User < ActiveRecord::Base; end class Organization < User; end 

(you need to specify the type field in the user table, which will be shared by both users and organizations)

They will share the database fields, and the Organization class inherits everything that the User has (including scopes and checks). This is very useful if your models are the same, since you can save everything DRY (you do not need to define anything extra).

 Organization.create(name: "thisisanorganization") #=> true (assume that name is unique) User.create(name: "penne12") #=> true (assume that name is unique) User.find_by(name: "thisisanorganization") #=> Organization User.find_by(name: "penne12") #=> User Organization.find_by(name: "thisisanorganization") #=> Organization Organization.find_by(name: "penne12") 

It may also be useful for you to create a parent class for the user and organization, so that users can have unique methods and checks from organizations (no password is needed in the organization, organizations belong to many owners (class: user), organizations must have a project, users have an email etc.)

Documentation

+2
source share

All Articles