Rails - get data of associated record - ruby-on-rails

New to RoR, I am trying to get the data of an associated record to display in an index.
I got this to work:
<td><%= annotation.documenttype_id %></td>
Yet want the value of the name field of the documenttype.
I am using Rails 5. Experiencing Rails so far, it has got to be so simple...

From your code i can get that the association is:
annotation belongs_to document_type
So you can access the document_type from annotation like this:
annotation.document_type.name

<td><%= annotation.document_type.field_name %></td>

Related

Using Heroku, Rails sort is incorrect on updated_at timestamp column

I have a Rails 4.0 APP using PostgreSQL on Heroku. I am trying to display a table that is my XLog or transaction log, showing the last five entries in reverse order by updated_at timestamp. This works correctly on my local system. When I push it to Heroku, it sorts incorrectly.
I have checked the Heroku database definitions and the column is correctly listed as a timestamp. I have cloned the Heroku code back to my machine and verified that it is the same as what I pushed. At this point, I don't know why it doesn't work on Heroku when it works locally. And advice would be appreciated.
FWIW, the remote database and local database do not have the same data.
The code is: (Last line of log_sort was added to act as a breakpoint that would still pass the correct result.)
def self.last_objects object, count
logs = XLog.where(object: object).last(count)
log_sort = logs.sort_by{|log| log.updated_at}.reverse
log_sort
end
During execution to the breakpoint, you can see the variables passed:
This is the local result with the correct sort:
This is the Heroku result with the incorrect sort:
This is the Heroku PostgreSQL table definition for updated_at:
EDIT: View:
<% xlog = xlog_last(car.stock_number, 5) %>
...
<% xlog.each do |log| %>
<tr>
<td><%= log.associate %></td>
<td><%= log.proxy %></td>
<td><%= log.action %></td>
<td><%= log.status %></td>
<td><%= log.message %></td>
<td><%= log.value %></td>
<td><%= log.updated_at %></td>
</tr>
<% end %>
Helper:
def xlog_last(object, count)
XLog.last_objects object, count
end
EDIT:
I modified the sort_by to use an order method as follows. The results did not change at all. The same sorting error occurred and the exact same data was displayed in the exact same way:
New code:
def self.last_objects object, count
logs = XLog.where(object: object).order(updated_at: :desc).first(count)
end
I believe you need to use order to influence the actual sql query. Right now you are using sort_by which is sorting the data after you read in from the database. The order in the db is based on how it was inserted and could be different from heroku and your local system. When you export from heroku, and then import it, the ordering of the tables probably changes too.
A gem was incorrectly sorting the view. Correcting that issue fixed the problem. Still unsure why it didn't show in test except possibly for the data differences.

Weird rails pluralization issue

I have a ruby on rails application that recently started giving me issues.
I believe there may be a weird bug/feature in the way rails is pluralizing model names for the database.
For example,
I have a model called DiagExerciceWeekFive. The table in the database is called diag_exercice_week_fives. The pluralization works correctly here.
I think there may be a problem in the way rails is attempting to "de-pluralize" the table into the respective objects.
When I try to load up a simple form that displays all of my diagweekfives, I get this error:
uninitialized constant Diag::DiagExerciceWeekFife
Not once have I used that name in my application.
Here's the relevant bit of code that is throwing the error:
<% ExerciceWeekFive.all.each do |exercice| %>
<tr class="success">
<td><%= check_box_tag :exercices_week_five_ids, exercice.id, #diag.exercices_week_fives.include?(exercice), :name => 'diag[exercices_week_five_ids][]' %></td>
<td><%= exercice.number %></td>
<td><%= exercice.description %></td>
</tr>
The exception is thrown on the first <td> within the <tr>
Has anyone run into this before? I know little about rails, but I am trying to maintain some legacy code.
Thanks.

Replacing foreign keys with data from table in ruby on rails

I'm brand new to ROR and very new to programming.
I'm working on a DB and I want entering information to be easy and user friendly. In my index pages for my tables any foreign keys are shown as the id. I would like to learn how to have it display a different column value instead of the id. For example company_name instead of company_id.
From my very little experience I would guess that the .map method would be used. I'm not really sure how though. I've already messed around with it for a while with no success.
The lower half of one of my table's index.html looks like this:
<% #venture_rounds.each do |venture_round| %>
<tr>
<td><%= venture_round.raise_amount %></td>
<td><%= venture_round.company_id %></td>
<td><%= venture_round.investor_id %></td>
</tr>
What can I do to have it grab a value from the company and investor table and show it, instead of the id for those tables?
I hope this question makes sense.
Make sure your VentureRound model has company and investor as defined children
class VentureRound < ActiveRecord::Base
belongs_to :company, :investor
end
Read the information as such
venture_round.company.location # or whatever attributes you're seeking
venture_round.investor.name

Displaying query results in rails

So in my model a user has many roles through assignments and a role can have many users through assignments. I've managed to get the function for creating new assignments up and running but I want to display all the roles a user can perform on the user index page (which lists all the users).
My code for the users stub view thus far is:
<td><%= user.email %></td>
<td><%= user.phone %></td>
<td><%= user.roles.select("description")%></td>
The problem here is that instead of displaying the description for the role the output is:
Any pointers would be much appreciated. Thank you in advance!
Map the relation into an array of the strings, so that:
<td><%= user.roles.select("description")%></td>
becomes:
<td><%= user.roles.select("description").map &:description %></td>
or:
<td><%= user.roles.select("description").map(&:description).join(", ") %></td>
to join it into a single comma-separated string.
Here it is
user.roles.select("description").map(&:description).join(", ")

ID is being displayed instead of the name

I have a has_many_and_belongs_to_many relationship between items and builds.
Whatever I do, I just cannot get the name of the items to be displayed for How do I output name instead of ID? and the rest. It just displays the ID :/.
In the code provided below, the ID of the items are being displayed instead of the name of the item with that ID. How do I display the name of the item?
<% current_user.builds.each do |build| %>
<tr>
<td><%= build.hero.name%></td>
<td><%= build.user.email%></td>
<td><%= build.name %></td>
<td><%= build.starting_items %></td>
<td><%= build.early_items %></td>
<td><%= build.core_items %></td>
<td><%= build.situational_items %></td>
</tr>
<% end %>
Here is the github repo: https://github.com/imjp/DotA-Items
Basically, what I want to do is to be able to enter the id of an item in my form that later on gets displayed as the item name.
I'm not even sure if the name starting_items is the best for this, or if i should just use item_id. Because I'm planning on adding a lot of different inputs where users can enter items that need to be displayed as names.
Do you think the name starting_items is good for one of the fields, or should I use item_id?
Isn't there a way I can display the name of an item with ruby by doing something like Item.name.find(build.starting_items) or something? Since the starting_items value is an item_id?
When you call build.starting_items which I assume is a named scope or method call you are probably returning an array of the items themselves.
Following this it's likely that each of the items if being inspected or you are seeing the output of item.to_s.
In order to display the names of these items instead of the object id you probably wish to use something like:
<td><%= build.starting_items.map(&:name).join(', ') %></td>
This will call map on the array and pass out each of the names and then join them (you could also use .to_sentence in Rails).
Looking at the code you are retrieving a list of all items from the database and using them to fill a semantic form. If you take a look at the output of the items in the html it is creating a list of options with the item id as the value of the select.
When the form is saved it saves a string containing the single item ID in the database.
Firstly if you need to accept multiple items you could specify a number of has and belongs to many relationships such as:
has_and_belongs_to_many :starting_items, :join_table => "items", :foreign_key => "item_id"
You then need to make sure that the form actually passed the item id's along to ensure that all of the id's are saved correctly.
Ok from re-reading what you've written in response to the other answer, I now guess that the column that you're having trouble with is:
<td><%= build.starting_items %></td>
(let me know if that guess is wrong and tell me the right one).
Rails doesn't automatically know that you want to see the names of these items. It will give you exactly what you've asked for - and here you have asked for the set of actual items... not the names of the set of items. To turn these item-objects into a list of the names of the items, you must call the "name" method on each item. you can do that using the code the other answer gave:
<td><%= build.starting_items.map(&:name).join(', ') %></td>
UPDATE
ok, reading through your codebase.
The problem is that you aren't actually saving the starting_items as actual items. In the form where you create a "build", you have the starting_items field as a select-box... the select box stores a set of ids. and id is just an integer value.
nowhere in your code do you turn that set of integer id values into actual Item objects.
So... when you go to look at that list once more... it's still just a set of integers.
To see the names of the Items that have those ids, you will need to actually instantiate those Item objects... and then call the 'name' method on them eg:
<td><%= Item.find(build.starting_items).map(&:name).join(', ') %></td>
Note: you'll also need to add basic checks eg that build.starting_items is not empty, and that the ids are in fact valid ids...
I seem to have figured this on my own after buying a Ruby book.
First, I created a new helper method in application.rb called starting_item which goes as follows:
def starting_item(id="6")
#item = Item.find(id)
"#{#item.name}"
end
Why helper method? This way I can call this method from within my views.
Now, to display the name of the item in my index view, I do just call the method with the argument as follows: <%= starting_item(build.starting_items) %>

Resources