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) %>
Related
The problem is this: I am showing some data to the user in a table and in it has a field of the numeric type that the user fills. However, I do not know how to send the value populated by the user as a parameter to the controller.
I've tried using the following syntax:
<td><%= number_field :stock, params[:amount] %></td> ## HERE IS THE PROBLEM
<td><%= link_to 'Buy', new_transaction_path(stock: {stock_id: "#{stock[:id]}", buy_price: "#{stock[:value]}", amount: "#{params[:amount]}", transaction_type: 'buy'}), method: :post %></td>
I would like to pass the value that the user informed thought the number_field as a parameter to the controller, but it's not working..
For your case "that the user fills", You have to user a form with a submit button, Here is a relate question, If the value is determined you can use link_to otherwise a form is better, Although sometimes I rely on JS or Jquery, I give the link_to a specific id and I give the input field and id too (HTML id), Then make an action listener on the the <a> that link_to generates, Once user click on it I get the data and submit the data.
The problem for the JS way is that if you are listing a table for more than one link_to for the product with multiple numeric_field you have to make sure that the id is unique, you can simply doing this by adding _#{id} part to the generated id.
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
I've built a small web app in which main view shows a table and administrator has an option to remove a row by deleting it from a database using:
*.destroy
However I want to keep all the entries in the database but still would like the option for the user to be able to remove the rows from the table and not sure how to go about this. I was thinking about using two different database tables but wanted to check if there is maybe a simpler way?
Here is my main view:
<h1>Student List</h1>
<table class ="Tables">
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Date Submit</th>
<th>Floor Preference</th>
<th></th>
</tr>
<% #students.each do |student|%>
<tr>
<td><%= student.f_name %></td>
<td><%= student.l_name %></td>
<td><%= student.created_at %></td>
<td><%= student.floor_pref %></td>
<td><%= button_to 'Remove', student, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New Student', new_student_path %>
you can easily do this by creating an extra column in same table with boolean value.
So extra column name can be isActive.
Removed row's isActive would be 0 and rest have 1.
And when fetching data just put extra check where isActive = 1
rails g migration AddActiveToStudents active:boolean
Then in view you can alter the value when they click the "Delete" button
Then put a check after the .each do |student|
<% if student.active %>
..........display..............
<% end %>
This solution is a little more labor intensive, but works for me. My steps are similar but I'll provide more detail because I'm new to programming so I'm going to assume there are others who are new as well:
Assumptions:
- You're working from a single model, views and controller (e.g. Model is Foo)
- You're able to delete a record from the db by clicking on a button that initiates a controller action ("Destroy")
- If you've got associations, destroying a record from the db is problematic to your app.
Created a migration for new column named is_active, w/datatype: boolean. Verify that rails created the migration correctly. If not, manually tweak the migration file. Make sure you bundle exec rake db:migrate after ANY change to the db. Restart your server.
Edit the destroy action in the controller by setting the is_active variable to false. Boolean evaluates to 'true' or 'false'. For us 'false' will represent a "deleted" row (although it won't be deleted in the database, just hidden from the view. e.g. #foo.is_active = false. Be sure to use the "=" operator, which assigns the value. In the view you'll use a different operator (==). Make sure you do a save after any editing. e.g. #foo.save. Also, comment out any destroy code. e.g. # #foo.destroy
2a. I also set the is_active value to 'true' in my create action. This may not be necessary but it works for me so far. If you made this adjustment, remember to save. e.g #foo.is_active = true, #foo.save
In the view where your results will show, add a conditional statement. I'm looping through my table and painting results. My if statement is after my do loop. If it evaluates to 'false' I'll show a line of text. ELSE, if it evaluates to 'true' I'll show my data. (Generally, on subsequent lines I have: Do Loop, 'False' iF Statement, Else, 'True' Data , End tag).
So, in the "if" statement I'm telling rails that when you're looping thru, if you see a row where the foo.is_active is 'false', show this text. Otherwise (else) show the data between 'else' and 'end'. Notice how the operator in the view is different than the controller. In the view we're checking for equality (==), not assigning a value to (=).
Make sure the variables that you're calling match what you've set in your controller's destroy action. They must be consistent or you'll get error messages. This gave me problems for a few hours before I figured it out. So if you're setting #foo in your controller, then you can only call #foo in your view.
Finally, the view I'm working with is my index but I also but a conditional statement in my show view so my users can toggle is_admin on or off. Using a simple_form_for form, I added the is_admin variable as boolean which shows as a checkbox on my show form. When checked is_admin is 'true' and the row will show. When unchecked is_admin is 'false' and therefore hidden.
I have Parent model and Child model.
Parent has many children.
In index.html.erb, I'm showing the number of records that each parent has.
But I bet it makes laggy when many people are accessing to this page at the same time.
<% #parents.each do |parent| %>
<td><%= parent.child.count %></td>
<% end %>
Should I create the column called 'count' in Parent table so that it won't need to calculate everytime it renders?
If this page, index.html.erb, will be often visited by your user, then I think you should make the 'count' column, maybe paired with counter cache, like this http://railscasts.com/episodes/23-counter-cache-column (sorry the video was old but it'll give you the idea).
Rails 2.3.5
I have a view displaying 'employee' records in a table where each table row haas a check_box_tag to select that (row) employee record (the table is inside a form_tag). The checkbox is passing an array of employee numbers to a method but I also need it to pass some of the other information from the record (first_name, last_name, etc) in the params.
Orignally this looked like (just passing an param with an array of employee numbers)
<% #employee_search.each do |e| %>
<td><%= check_box_tag 'selected_subordinates[]', e.employee_number %></td>
<td><%= e.employee_number %></td>
<td><%= e.first_name %></td>
<td><%= e.last_name %></td>
...
<% end %>
I'm not sure this was right, but I thought I should pass the entire record ('e') in the param:
<% #employee_search.each do |e %>
<td><%= check_box_tag 'selected_subordinates[]', e %></td>
<td><%= e.employee_number %></td>
<td><%= e.first_name %></td>
<td><%= e.last_name %></td>
...
<% end %>
The param array now looks like:
"selected_subordinates"=>["#<Employee:0xa946970>", "#<Employee:0xa946910>", "#<Employee:0xa9468b0>"]
I thought at this point I would be fine and just itterate through the objects in the param array referring to the record fields, but got an undefined method error:
params[:selected_subordinates].each do |s|
puts s.last_name
end
undefined method `last_name' for "#<Employee:0xa946970>":String
I started wondering if for some reason the entire model object was passed instead of just one record from the object. But, trying [0].last_name resulted in a different error.
params[:selected_subordinates].each do |s|
puts s.last_name
end
undefined method `last_name' for 35:Fixnum
Maybe I should have been using the fields I need to build an array for the param - so the param would be an array of arrays? I haven't had any luck so far trying to search for example of what to do when you need to setup a param array made of arrays, or pass a single model object record (and refer to it).
Thank You - Much Appreciated!
When you used e as the param, Rails was converting e to a String and passing that (you can't pass an object in an HTML form, right? Just values). When you saw "#<Employee:0xa946970>" in your params hash, it wasn't an Employee object, but instead a String with the contents of #<Employee:0xa946970> (which is what you get if you called .to_s on an Employee object).
Passing the ID gets you on the right track, but once you have the ID, you should look up the Employee with that ID from the database.
params[:selected_subordinates].each do |s|
employee = Employee.find(s)
puts employee.last_name
end
Of course, this loads them one at a time, so if you have a lot of checkboxes you could end up generating a large number of queries. You can also use the find method to find multiple objects based on an array of IDs:
employees = Employee.find(params[:selected_subordinates])
employees.each do |e|
puts e.last_name
end