Using gettext with content from database in phoenix app? - translation

I'm trying to use Gettext and domains in a phoenix app to translate "materials" (wood, wool, cotton, kapok...).
Materials come from a database.
This works:
<%= MyApp.Gettext.dgettext "materials", "cotton" %>
But this does not:
<%= MyApp.Gettext.dgettext "materials", "#{material.name}" %>
I'm trying to add the translation to a template
<%= for material <- #materials do %>
<td><%= AmazingApp.Gettext.dgettext "materials", "#{material.name}" %></td>
<% end %>
How can one go about translating in this situation?

You can use Gettext.dgettext/3 for this:
<%= Gettext.dgettext(MyApp.Gettext, "materials", material.name) %>
From the documentation:
Dynamic translations should be avoided as they limit Gettext's
ability to extract translations from your source code. If you are
sure you need dynamic lookup, you can use the functions in the Gettext
module:
string = "hello world"
Gettext.gettext(#{inspect(gettext_module)}, string)

Related

How to extract grouped results from single model/table and provide to the view

I have a model called Language, with just two columns: language and link, and would like to be able to loop through each link for each language and display in the view. i.e. (obviously this isn't code, it's just to illustrate the desired pattern)
Language 1
Link 1
Link 2
Link 3
Language 2
Link 1
Language 3
Link 1
Link 2
Language 4
etc
What is the 'rails way' of extracting this data, and then presenting in the view? (note: I would know how to do this easily if the data were in two different models, but it isn't)
So, a Railsy way would be to use the following in your controller:
#languages = Language.all.group_by(&:language)
This will give you a hash of languages grouped by the (erm...) language's language (<- perhaps rename the column to name to avoid this ambiguity?):
# { 'English' => [language_1, language_2, etc...],
# 'French' => [language_3, language_4],
# etc... }
And then this in your view:
<% #languages.each do |language_name, languages| %>
<h1>
<%= language_name %>
</h1>
<% languages.each do |language| %>
<p>
<%= language.link %>
</p>
<% end %>
<% end %>
Obviously the HTML tags can be whatever you'd like, though I hope that gives a useful example.
However, there's a caveat here - as your database grows, this might not prove an efficient way of working. You'll likely be better off setting up a separate model for links, with a one-to-many relationship between languages and links.
For example:
# langage.rb
has_many :links
# link.rb
belongs_to :language
# your controller
#languages = Language.includes(:links)
And then something like the following in the view:
<% #languages.each do |language| %>
<h1>
<%= language.language %>
</h1>
<% language.links.each do |link| %>
<p>
<%= link.url %>
</p>
<% end %>
<% end %>

Printing string inside nested hash - Ruby

I have been trying to learn the ropes of ruby for a Rails project that I picked up. I have C++ experience but am still learning my way around Ruby, so I will apologize now for not understanding Ruby and its nuances.
I have a hash that has elements containing another hash of strings...
def directors = {
gm: { pos: "General Manager", email: "123#abc.com" },
prod: { pos: "Production Director", email: "456#def.com" },
support: { pos: "Support Director", email: "789#xyz.com" }
}
end
Within html I am able to run ruby code to access and output each respective string individually...
<%= directors[:gm][:pos] %>
<%= directors[:gm][:email] %>
<%= directors[:prod][:pos] %>
<%= directors[:prod][:email] %>
<%= directors[:support][:pos] %>
<%= directors[:support][:email] %>
This is a tedious and manual way to obtain and output every single element. I am attempting to write this in a more concise manner and in a way so that it will always display every element regardless of knowing how many elements are in each. I can write directors.each to call each element inside directors, but I need to again access each element inside of each director element. This is the best code I could come up with, but is not syntactically correct.
<% directors.each do |director| %>
<% "#{director}" do |info| %>
<%= dirs[:"#{director}"][:"#{info}"] %>
<% end %>
<% end %>
If you just want to display the nested hash, you can do so like this:
<% directors.each do |_internal_name, details| %>
Position: <%= details[:pos] %>
Email: <%= details[:email] %>
<% end %>

Rails instance variable join

This is so simple but it's been ages since I needed this.
I have the following code
<% #miniature.minisets.each do |miniset| %>
<%= link_to miniset.name, miniset %>
<% end %>
It outputs Minisetname Minisetname Minisetname etc
I want it to output Minisetname, Minisetname, Minisetname with commas.
I've tried to include .join(", ") but can't find the right place to put it. Do I also need to use .map instead of .each?
Ignominy.
Here's one way that ought to work:
<%= #miniature.minisets.map { |miniset| link_to miniset.name, miniset }.join(", ").html_safe %>

Creating Links on Rails

I've just started using rails yesterday, so this is a kinda noob question
for example, a user is at www.example.com/name
and I want to make several links to www.example.com/name/:id
So I tried something like this:
<% #items.each do |item| %>
<%= link_to item.name, '/name' :id %>
<% end %>
I know, it was a complete guess on how I should write the code, but the restful code sends to a completely wrong link. How should I write this three lines?
Use the route helper:
<% #items.each do |item| %>
<%= link_to item.name, item_path(item) %>
<% end %>
ps: when you have a simple question like this one, take a look at this guide, you'll often find the answer.
Try
<%= link_to item.name, item_path(item) %>
item_path is a URL helper method which spits out the link to show a name.
URL helpers have the general form:
{action}_{class}_path({object or object_id})
If {action}_ is omitted, then the default action is assumed (normally show).

How do I run multiple lines of Ruby in html.erb file

I'm using Ruby on Rails and need to run a block of Ruby code in one of my html.erb files. Do I do it like this:
<% def name %>
<% name = username %>
<%= name %>
or like this:
<% def name
name = username %>
<%= name %>
Thanks for reading.
If you need extra functions in your view, you normally declare those inside a helper.
For each controller, if there is a helper it is automatically loaded. For instance, if you have a PeopleController, in the app/helpers folder, there should be a people_helper.rb, and it should look like this
module PeopleHelper
def name
#do something
username
end
end
Another, very clean alternative, is to use the Presenter pattern, but i think it is less common (unfortunately).
Otherwise, if you do need multiple lines of ruby code inside a erb view, which i try to avoid, i prefer the following style:
<%
counter_1 = 0
counter_2 = 1
do_some_more_prep_here
%>
<% #records.each do |rec|%>
<%# do something with the prepped date in each row %>
<% end %>
Also for me code indentation is more important than html indentation, so i will prefer something like
<table>
<% #rows.each do |row| %>
<tr>
<td><%= row.item1 %></td>
<% if row.some_test %>
<td><%= row.item2 %></td>
<% end %>
</tr>
<% end %>
</table>
But i am always very interested to hear different opinions in this matter.
It is unusual to define a method in an ERB file, so I recommend against it.
If you want to call a block like #each, you can do something like the following:
<% names.each do |name| %>
<%= name %>
<% end %>
Don't forget the <% end %>.
I can imagine someone needing it in one particular template (no point in creating a helper) to not duplicate html markup. That is, when resulting html page has a couple of similar blocks of html markup. Though, it can easily be abused (unreadable code).
<% def f1(a, b, c) %>
test: <%= a %>, <%= b %>, <%= c %>
<% end %>
<% f1(1, 2, 3) %>
<% f1(4, 5, 6) %>

Resources