Skip to content

Commit 6286185

Browse files
authored
Merge pull request #131 from github/additional-styleguide-rules-from-web-systems
Add Rails recommendations to styleguide
2 parents c79e440 + 72beaf6 commit 6286185

File tree

1 file changed

+128
-0
lines changed

1 file changed

+128
-0
lines changed

STYLEGUIDE.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ This is GitHub's Ruby Style Guide, inspired by [RuboCop's guide][rubocop-guide].
2727
1. [Conditional keywords](#conditional-keywords)
2828
2. [Ternary operator](#ternary-operator)
2929
17. [Syntax](#syntax)
30+
18. [Rails](#rails)
31+
1. [content_for](#content_for)
32+
2. [Instance Variables in Views](#instance-variables-in-views)
3033

3134
## Layout
3235

@@ -893,4 +896,129 @@ result = hash.map { |_, v| v + 1 }
893896

894897
Refactoring is even better. It's worth looking hard at any code that explicitly checks types.
895898

899+
## Rails
900+
901+
### content_for
902+
903+
Limit usage of `content_for` helper. The use of `content_for` is the same as setting an instance variable plus `capture`.
904+
905+
``` erb
906+
<% content_for :foo do %>
907+
Hello
908+
<% end %>
909+
```
910+
911+
Is effectively the same as
912+
913+
``` erb
914+
<% @foo_content = capture do %>
915+
Hello
916+
<% end %>
917+
```
918+
919+
See "Instance Variables in Views" below.
920+
921+
#### Common Anti-patterns
922+
923+
**Using `content_for` within the same template to capture data.**
924+
925+
Instead, just use `capture`.
926+
927+
``` erb
928+
<!-- bad -->
929+
<% content_for :page do %>
930+
Hello
931+
<% end %>
932+
<% if foo? %>
933+
<div class="container">
934+
<%= yield :page %>
935+
</div>
936+
<% else %>
937+
<%= yield :page %>
938+
<% end %>
939+
```
940+
941+
Simply capture and use a local variable since the result is only needed in this template.
942+
943+
``` erb
944+
<!-- good -->
945+
<% page = capture do %>
946+
Hello
947+
<% end %>
948+
<% if foo? %>
949+
<div class="container">
950+
<%= page %>
951+
</div>
952+
<% else %>
953+
<%= page %>
954+
<% end %>
955+
```
956+
957+
**Using `content_for` to pass content to a subtemplate.**
958+
959+
Instead, `render layout:` with a block.
960+
961+
``` erb
962+
<!-- bad -->
963+
<% content_for :page do %>
964+
Hello
965+
<% end %>
966+
<%= render partial: "page" %>
967+
<!-- _page.html.erb -->
968+
<div class="container">
969+
<%= yield :page %>
970+
</div>
971+
```
972+
973+
Pass the content in a block directly to the `render` function.
974+
975+
``` erb
976+
<!-- good -->
977+
<%= render layout: "page" do %>
978+
Hello
979+
<% end %>
980+
<!-- _page.html.erb -->
981+
<div class="container">
982+
<%= yield %>
983+
</div>
984+
```
985+
986+
### Instance Variables in Views
987+
988+
In general, passing data between templates with instance variables is discouraged. This even applies from controllers to templates, not just between partials.
989+
990+
`:locals` can be used to pass data from a controller just like partials.
991+
992+
``` ruby
993+
def show
994+
render "blob/show", locals: {
995+
:repository => current_repository,
996+
:commit => current_commit,
997+
:blob => current_blob
998+
}
999+
end
1000+
```
1001+
1002+
Rails implicit renders are also discouraged.
1003+
1004+
Always explicitly render templates with a full directory path. This makes template callers easier to trace. You can find all the callers of `"app/view/site/hompage.html.erb"` with a simple project search for `"site/homepage"`.
1005+
1006+
``` ruby
1007+
def homepage
1008+
render "site/homepage"
1009+
end
1010+
```
1011+
1012+
#### Exceptions
1013+
1014+
There are some known edge cases where you might be forced to use instance variables. In these cases, its okay to do so.
1015+
1016+
##### Legacy templates
1017+
1018+
If you need to call a subview that expects an instance variable be set. If possible consider refactoring the subview to accept a local instead.
1019+
1020+
##### Layouts
1021+
1022+
Unfortunately the only way to get data into a layout template is with instance variables. You can't explicitly pass locals to them.
1023+
8961024
[rubocop-guide]: https://github.com/rubocop-hq/ruby-style-guide

0 commit comments

Comments
 (0)