Issue with Rails 5.2.4 translation method - ruby-on-rails

The index view pushed by the Scheduler::ProductionJobsController index method contains the following request to the translation method:
<h2> <%= t('.View') %> </h2>
The config\locales\Scheduler\ProductionJob\ fr_OFS.yml file (which is current user's language) contains the following entries:
# Code for language as declared in i18n configuration
fr_OFS:
# Considered object from a global view
ProductionJobs: "Flux de production"
# Considered object from controller's methods. In the controller, the relative path for the term is marked by the point (.)
scheduler:
production_jobs:
index:
# Columns titles
Code: "Identifiant"
Name: "Nom"
Description: "Description"
Owner: "Responsable"
Version: "Mis à jour le"
Status: "Statut"
View: "Voir"
Delete: "Supprimer"
Eventhough this looks trivial, it results in a translation missing error:
<h2>
<span class="translation_missing" title="translation missing: fr_OFS.scheduler.production_jobs.index.View">View</span>
</h2>
Writing t('scheduler.production_jobs.index.View') does not change a thing...
Did I miss something?
Thanks for your help!

Related

Syntax differences between method calls and variable calls in embedded ruby scripts?

This might be a noob question but here it goes:I'm trying to parse embbeded ruby code and I need some help in understanding the synthax for methodcalls and variable accesing in embedded ruby scripts.
For example in this call #user.followed_users.count (as I understand it) #user is an instance of a the user model followed_users is a (automatically generated) method and count is also a method right?
But what are these calls micropost.content micropost.created_at micropost.user? They are from this erb file:
<li>
<span class="content"><%= micropost.content %></span>
<span class="timestamp">
Posted <%= time_ago_in_words(micropost.created_at) %> ago.
</span>
<% if current_user?(micropost.user) %>
<%= link_to "delete", micropost, method: :delete,
data:{ confirm: "You sure?" },
title: micropost.content %>
<% end %>
</li>
(these are code examples from this michael hartl rails tutorial)
What kinds of syntaxes for method calls and variable accessing from erb files are there in Rails? Is it possible to access variables from ruby files that are not instance or class variables?
Thanks in advance for reading and helping :)
The syntax is the same.
There are no major syntactical differences between ERB and Ruby except that ERB is an embedded language where only the code in "erb" tags are executed <% %>.
Whats the difference between a local variable and a method?
A method is a method object that is defined on an object.
def foo
"hello world"
end
# we can call it by
self.foo
# we can access the method object by
self.method(:foo)
This defines the method foo on main.
bar = "value"
Defines the locally scoped variable bar. Not that you can't do self.bar since it just points to a memory register, not a method! You don't call variables - you reference them*. Thus the term "variable call" is just wrong.
As #SergioTulentsev points out you can check if a micropost is a local variable or method by using defined?. Note the caveat when using rails locals below.
See:
What is the difference between local, instance, and class variables?
Using ERB outside of rails
In Ruby the top level object is called main which is the "global" object.
When you assign a instance variable <% #foo = "bar" %> you are assigning it to main which is the implicit self.
<%# raw_template.erb %>
<%= self.inspect %>
If we run erb raw_template.erb it will output main.
Assigning a regular lexical variable (a local) <% foo = "bar" %> works just like in any other ruby code.
As you can see is no difference in how variables work in an ERB template and any other Ruby code.
What does rails do differently?
A core piece of Rails is what is called the view context. This is an instance of ActionView::Base which is the implicit self - the "global" object.
You don't have to take my word for it. Try including this in a view in Rails:
<pre>
<%= self.inspect %>
</pre>
Rails takes all the instance variables of the controller and assigns them to the view context. Which why the #something instance variable you assign in your controller is also available to your views.
Rails locals are not really local variables
The view context also contains a hash called local_assigns. These are the "local variables" you can pass when rendering a template:
render template: 'test', locals: { foo: 'bar' }
When you call <%= foo %> in the test.html.erb template the call goes to method_missing which checks if local_assigns has a :foo key.
Thats why using defined? on local_assigns variables does not work as expected.
But the syntax is the same.
Rails uses a bit of metaprogramming magic to pass variables around - but it does not alter the syntax of the language.
Is it possible to access variables from ruby files that are not
instance or class variables?
Yes, global variables - in Ruby you create a global variable by using the sigil $.
$foo = "bar"
But this is rarely used because globals are evil. And there are better ways to it in Ruby.
micropost in <%= micropost.content %> can be a local variable OR a method. There's no way to tell which is it, just by looking at the line. All that matters is micropost evaluates to something you can call .content on.
If you want to know which is it (for education), you can output its type like this:
<%= defined?(micropost) %>
It'll return either "local-variable" or "method" (or nil, if it's not defined).

Accessing the model's attribute translations when displaying error

I've successfully created my he.yml to localize my model's attributes names,
example:
attributes:
vendor:
name: שם ספק
counter_number: מספר חשבונית
phone: טלפון
address: כתובת
Now, displaying labels in forms using simple_form's f.input, displays it correctly, the translated value of each attribute.
the problem is, displaying errors after validation, using
<% #vendor.errors.each do |attribute, error| %>
|attribute| for error "counter_number" for example, is displayed: "counter_number".
not the translated one at the locale file [which as i mentioned previously, configured and loaded successfully].
I appended errors in a ul.errors, as shown in this screenshot:
Thanks in advance.
You can do something like this:
#vendor.errors.messages do |attribute, errors|
translated_attribute = Vendor.human_attribute_name(attribute)
errors = errors.join(", ")
end
I've tested this with my User model:
The following is just an example to complete your provided code.
<% #vendor.errors.each do |attribute, error| %>
<strong><%= t("activerecord.attributes.#{#vendor.class.to_s.underscore}.#{attribute}") %>:</strong>
<%= error.messages.to_sentence %>
<% end %>
Maybe there is an easier approach than this.

How to lookup i18n translations in nested yaml file in Rails 4.2?

Under 4.1.4 "Lazy" Lookup, if you have the following dictionary:
es:
books:
index:
title: "Título"
you can look up the books.index.title value inside app/views/books/index.html.erb template like this (note the dot):
<%= t '.title' %>
But if I alter the dictionary like this:
es:
books:
index:
title: "Título"
author:
first_name: "Jane"
Then:
<%= t '.first_name' %>
gives a missing translation error.
1) Is there a limit on the nesting depth you can have?
2) Can you setup custom hash keys via yaml (for example, suppose instead of "index" as a key I want to use "kite", even though kite is not an actual view) and if so how?
No, there is no limit on the nesting depth, it's only that you're not following the "logic" behind it:
the '.' in '.first_name' refers to the controller + action in your page, in this case books: index: - so if you want to access author: first_name:, you should put '.author.first_name' in your index file.

Document partial parameters in Rails

Is there any standard or emerging standard to document the parameters that can be passed into a Rails partial ?
When _my_partial.html.erb expects a title and an elements local var passed with render 'my_partial', title: t, elements: e, there must be a common way to document their names, expected types and roles, without reading the whole partial code. Something like RDoc or Tomdoc for methods and classes. Isn't there ?
Edit: I've found a post whose author advocates initializing parameters with <% var ||= 'default_val' %> in the first lines of the partial, which is indeed a safe practice and a kind of in-code doc. Is there really no comment/parameter-declaration solution for this ?
At the beginning of your partial, simply call all the variables that are referenced.
# _my_partial.html.erb
<% title %> <--- first line of file
<% elements[0] %>
<h3><%= title %></h3>
<% elements.each do |element| %>
<p> etc ... </p>
Reasons why this is good for your project:
it does not rely on comments or non-code files
any developer on the project can quickly find out which variables are needed by looking at the top of the file in question
by calling the variables, you ensure that a missing variable will result in an exception.
elements is called with square brackets because we also want it to blow up if it's not an enumerable, right?
The practice of using <% var ||= 'default_val' %> is actually unsafe because it allows bugs to hide. You want your code to immediately blow up the moment something isn't done right. And if these variables should be passed, then you want the code to blow up when they're not there.

Missing template

so i have this code:
<% form_tag(:action => 'find') do%>
Product name:
<%= text_field("cars_", "name", :size => "30") %>
<input type ="submit" value="Find"/>
<%end%>
upon pressing the button I want it to complete the method (def find) found in the controller but its requesting the html.erb file:
Template is missing
Missing template cars/find.erb in view
path H:\Documents and
Settings/owner/My
Documents/NetBeansProjects/RailsApplication5/app/views
in the find def (found in controller)
def find
#car = Car.new(params[:car_])
end
What is the last line of your find method? Generally, if you don't specify the template to render in your controller method, Rails attempts to find a template with the same name as the method. That is why it is saying it can't find cars/find.erb. Without seeing the code in your find action, it is hard to give a better answer.
Your find method should be doing some searching, not initializing with the parameters. I recommend checking out something like thinking sphinx or searchlogic if you want to do searching.
I believe that your code is executing the find action. However, after it finds the car object, it needs to write that into a template that shows the results of your search. By convention, rails looks for a file called find.html.erb in the view folder for that controller. So, the error message you are seeing means that Rails has executed the line of code in your action and is now trying to generate some HTML to send back to the browser
If you create a simple file in the view folder for that controller with contents:
<%= #car.name %>
You should see the results.
However, your code is a bit confusing to me as I don't know why a find method would create a new Car object. I would expect something like this:
def find
#car = Car.find_by_name(params[:name])
end
I would also expect that your form would be more like:
<% form_tag(:action => 'find') do%>
Product name:
<%= text_field_tag("name", :size => "30") %>
<%= submit_tag "find" %>
<%end%>

Resources