You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: _posts/2020-06-01-embracing-perspectives-with-the-rails-router.md
+11-11Lines changed: 11 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,7 @@ tags : software
8
8
9
9
One of my favorite parts of Rails is the [router](https://guides.rubyonrails.org/routing.html).
10
10
11
-
If you peek behind the curtain it has a number of interesting things going on.
11
+
If you peek behind the curtain it has several interesting things going on.
12
12
Some of these include:
13
13
14
14
* Domain Specific Langage (DSL) for mapping routes to controller actions.
@@ -23,7 +23,7 @@ There's a ton to cover, and perhaps I will in future posts, but for this post, I
23
23
In my opinion, it's very easy for Rails developers to fall into the thought process of:
24
24
25
25
1. I have an ActiveRecord model named `Foo`
26
-
1. I should make an`FoosController`
26
+
1. I should make a`FoosController`
27
27
1. All actions involving a `Foo` go into the `FoosController`
28
28
29
29
Ignoring the first point's ActiveRecord assumption, since I think it deserves its own post...
@@ -44,7 +44,7 @@ resource :jedis
44
44
Here I define a "jedis" resource.
45
45
As a result, Rails expects me to define a controller called `JedisController` located in `app/controllers/jedis_controller.rb`.
46
46
47
-
In addition, each controller action is now expected to have a "view" located in a directory that corresponds with the resource:
47
+
Also, each controller action is now expected to have a "view" located in a directory that corresponds with the resource:
48
48
49
49
```
50
50
/app
@@ -55,7 +55,7 @@ In addition, each controller action is now expected to have a "view" located in
55
55
56
56
## Nested Resources
57
57
58
-
Eventually your app gains a requirement where it will grow some sort of nesting.
58
+
Eventually, your app gains a requirement where it will grow some sort of nesting.
59
59
For instance, I imagine our jedis will need some lightsabers.
60
60
61
61
```ruby
@@ -73,7 +73,7 @@ One with the force and all that noise.
73
73
## It's a Trap!
74
74
75
75
If you're anything like me, you'd agree that lightsabers are interesting in their own right.
76
-
Perhaps we want to list all the lightsabers independently of the jedi that happen to wield them.
76
+
Perhaps we want to list all the lightsabers independently of the jedi that happens to wield them.
77
77
Maybe they've been wielded by multiple jedi over time (tell me more!).
78
78
79
79
Goofy example aside, I've found wanting multiple perspectives of the same data to be a common pattern in large Rails apps.
@@ -95,7 +95,7 @@ This code expects the same controllers to be defined as before, but now we have
95
95
```
96
96
97
97
This is problematic because two routes now map to the same controller endpoint.
98
-
Last one wins.
98
+
The last one wins.
99
99
**Confusion ensues.**
100
100
101
101
What I've seen most people do at this point is break out of the CRUD methods and define a one-off action in the controller -- or worse yet, add a `if params[:jedi_id]` condition.
@@ -124,24 +124,24 @@ As a result, Rails now expects me to define **3** controllers:
124
124
*`LightsabersController` located at `app/controllers/lightsabers_controller.rb`
125
125
***`Jedis::LightsabersControllers`** located at `app/controllers/jedis/lightsabers_controllers.rb`
126
126
127
-
This allows both `LightsabersController` and `Jedis::LightsabersController` to define their own `show` action, which of course have their own url helpers: `lightsabers_path` and `jedis_lightsabers_path`, respectively.
127
+
This allows both `LightsabersController` and `Jedis::LightsabersController` to define their own `show` action, which of course have their own URL helpers: `lightsabers_path` and `jedis_lightsabers_path`, respectively.
128
128
129
-
In addition, you now have an `app/controllers/jedis` directory and `Jedis` namespace to places all of the other resources that are from the perspective of a jedi.
129
+
Also, you now have an `app/controllers/jedis` directory and `Jedis` namespace to places all of the other resources that are from the perspective of a jedi.
130
130
131
131
As you may have guessed, this organizational pattern extends to the view as well.
132
132
This is great since the way you display a lightsaber by itself vs in the context of a specific jedi may vary greatly (this holds true when rendering JSON in an API scenario as well!)
133
133
134
-
This may seem like a minor change at first, but in my experience it can have a significant impact on how code is organized and discovered.
134
+
This may seem like a minor change at first, but in my experience, it can have a significant impact on how code is organized and discovered.
135
135
136
-
Personally, I'd recommend taking this approach for _every_ nested resource.
136
+
I'd recommend taking this approach for _every_ nested resource.
137
137
Interestingly, after taking this approach, I find little reason to break out of the default CRUD actions -- just define a new controller!
138
138
139
139
## A Parting Note
140
140
141
141
Over time, Rails has developed a specific interpretation of [REST](https://en.wikipedia.org/wiki/Representational_state_transfer).
142
142
Like anything, depending on your use case, it may not always suit your needs.
143
143
144
-
Personally, I've found the sweet spot to be serverrendered applications (gasp!) and APIs with concrete use-cases.
144
+
I've found the sweet spot to be server-rendered applications (gasp!) and APIs with concrete use-cases.
145
145
146
146
However, regardless of how you use the rails router, don't fall into the trap of thinking your <spantitle="Read: Not limited to ActiveRecord">domain representations</span> must be 1-1 with a controller.
0 commit comments