Where to store static variables and constants for view in RoR?

Good afternoon everyone. I mostly do front end (now more than vue, but familiar with angular), with rails work according to the circumstances (the backend of many projects I'm working on, written in rails). I'm having a small problem with understanding some of the basic concepts on which to build this framework. And the issue concerns the representation of data, i.e. more to do with the vyuha and associated logic.

Suppose the application has a menu, which presents a set of links: event, archive, blog, account, language, entry_btn. A few of the buttons have conditional dependencies, for example: button language selection depends on the current selected language, the content of the button entry_btn and the presence of a button account depends on logged user or not.

the most simple, obvious and well working solution:
/ slim-lang
 li = link_to 'Events', root_path, class: 'navbar__item'
 / ... other links

 - if I18n.locale == :EN
 link_to 'Eng', locale_path(:en) 'navbar__item'
 - else
 link_to 'EN', locale_path (ru), 'navbar__item'

 - if signed_in?
 li = link_to 'Account', edit_user_registration_path, class: 'navbar__item'
 li = link_to "Exit", destroy_user_session_path, class: 'navbar__item', method: :delete
 - else 
 li = link_to 'sign in', new_user_session_path, class: 'navbar__item'

This translates into writing a snippet for each menu item and, as a consequence, a huge amount of code, but I want to do something a little more compact to view the size occupied by the lines of 20-30, not 120. My solution was to raise the level of abstraction by removing specific references to the array and the output link through the iteration over the array. Roughly something like this:

/ slim-lang
- links = [{ label: 'Events', path: root_path }, ... ]
- links.each do |link|
 li = link_to link[:label], link[:path], class: 'navbar__item'

But this approach still remain problems with conditional links. In General, after sitting a few hours with speci Rohr, I came to the conclusion that I have created a Navbar class, in which he made the right navbar set of methods to display links, reduced all the code to a simple design:
/ for the layout I had to split the list into 2 diva, so that the transmitted characters in the method need to search for objects
- @navbar.links(:root, :archive, :blog, :locale, :entry_group).each do |link|
 li = link_to link[:label], link[:path], class: 'navbar__item', **link[:options]

Inside navbar:
class NavbarPresenter < BasePresenter
 include Rails.application.routes.url_helpers

 def links *args
 methods = args.select { |method| self.respond_to? method, :include_private and available_links.include? method }

 links = methods.map { |method| self.send method }


 def format_link label, path, **args
 { label: label, path: path, options: args }

 def available_links
 [:root, :archive, :blog, :locale, :entry_group]

 def blog
 format_link I18n.t('header.items.blog'), posts_path

 # ...
 # other links with different logic 

Works as I need, this problem does not arise. But, actually, questions I have the following:
  1. What type of entity it is? On the one hand, it has the logic of the presenter (in ruby terminology), i.e., transform the data I need to view function way on the other - has no model for representation has only static dataset defined in itself (i.e. an array of references). Initially I did it as NavbarPresenter, but now doubted
  2. Where do I initialize it? I now declare it as a variable inside application_controller @navbar = NavbarPresenter.new(view_context), but he's so available all the vyuha, and I would like to make it available only inside navbar (navbar I have a partial)
  3. Where am I to place it? In the presenters? I think, inside it is executed and the logic model MenuLinks and the logic of the presenter to the model. Break it down into different entities? Is it permissible to add MenuLinks model, which simply defines a set of links to navbar or is it taskbar?
  4. Is it reasonable in the same way to make classes to control the logic of different vyuha? I understand that you can make a normal and logical presenter for models, for example, for Event, User, etc, use them in the vyuha, but is it wise to do this for "static" entities, which change is not expected (at least often) are not the model as such? I mean I have made the difficult slider, it has conditional logic, there are a few constants (the index of the first slide, max number of slides, slider id, etc.). If I wrote this on the vue, you would never use in the vyuha "sugardaddie" values, and would have carried them into the variables in the store, anywhere but view function

If you think I wrong look at ROR and need to put all this logic in the view, please let me know, I will be useful to know a second opinion.
March 19th 20 at 09:03
2 answers
March 19th 20 at 09:05
The method links have no place in the controller. Move the method into a separate helper or use gem cells
he's not in the controller, the controller initializing the presenter occurs, which has a method links. - Erik_Rosenba commented on March 19th 20 at 09:08
@Erik_Rosenba, sorry, did not notice. But I still think that you have overthought decision. It makes sense to use the presenter, if you have the menu only contains ranting and their names? - Ahmed commented on March 19th 20 at 09:11
@Ahmed, thanks for the answer )

Actually, the question is more about is whether to use a classroom which can accommodate the logic for the view function? Ie, instead of building up the set of conditional structures, duplicating the layout, I just can't stand the logic in the ruby file where all logic and place, in fact. And in the view I have, instead of 10 identical blocks with links only 2 lines: cycle and layout for part of a cycle that, in my opinion, very logical and compact.

And, as a consequence, from the first question raises a second: if I have a view function logic in a separate ruby class responsible for representation of the data for the view function, then what is the essence of such a class include? Presenter - this is my primary answer, but I wondered, in this and decided to consult with the community :) - Erik_Rosenba commented on March 19th 20 at 09:14
March 19th 20 at 09:07
It is not clear why all this inventing. Than bad just a lot of links in the presentation, what this code flaw? Than the ability to display the links in the cycle justifies the introduction of a new abstraction. The more that You do not care for each link a separate method, not just in performance, but in presenter. Just imagine how complicated the code if for example you have to add a check on the accessibility of links to the user depending on his rights.

But, if the answer to the question of how You understand the conventions of the framework, then there are no limitations. You can come up with your essence and create folder with any name. The main thing that other developers it was clear why this was done and what the rules of these entities, what code they should be stored.

You can even just make a separate helper that will probably be the most standard option. But IMHO if You have a sat NAV in a separate partiale, it is a closed unit and can all be put back. There is no perfect code that always compromises
Thanks for the reply!

Than bad just a lot of links in the presentation, what this code flaw?

Bad because in methods I, except for label, address, and conditions, nothing, then as you create each block of your layout under a separate link just increases the volume of the same code. Bad the final layout without this abstraction will have multi-level conditional constructs, whereas hiding the implementation of checking each individual link in methods makes the code more flat and easy to grasp, I think.

as more complicated code, if for example you have to add a check on the accessibility of links to the user depending on his rights

it seems to me that the code is not very complicated, since this check I have already present in the methods. For example:
class NavbarPresenter < BasePresenter
# ...
 def locale
 label = I18n.locale == :EN ? 'ENG' : 'EN'

 path = I18n.locale == :EN ? h.locale_path (en) : h.locale_path(:EN)

 format_link label, path

 def sign
 if h.signed_in?
 format_link I18n.t('header.items.logout'), destroy_user_session_path, method: :delete
 format_link I18n.t('header.items.login'), new_user_session_path

I have omitted this code from the example to reduce the scope of the issue, but in General it works without problems in this regard.

And, in General, navbar and links here just put in an example, the main question is, is it worth to make the extra logic from the view function when she's clearly not a place separate entity? and if so, what is the essence if the logic associated with the static information, a set of parameters, not the model? - Erik_Rosenba commented on March 19th 20 at 09:10
Bekendste too many other problems to deal with, usually about how to get links to not really think.

But as I wrote above, Your approach is quite the place to be. Except that the presenter still considered to be a class that combines complex data structure, but the output of this structure should still be in your layer - the presentation layer - kallie_Purdy commented on March 19th 20 at 09:13

Find more questions by tags Patterns of designingRuby on Rails