Background info: A Deal has many coupons (#freeDeals contains all those coupons) and a coupon belongs_to a Deal.
Controller:
#freeCoupons = Coupon.where(discount: 100).order("created_at DESC").page(params[:page])
#deals = Deal.all
This code below works exactly like I want and finds the title for the deal (hard coded in the 2 for testing purposes)
<% #freeCoupons.each do |f| %>
<%= #deals[2][:title] %>
<% end %>
But when I switch it over to trying to find the title of the deal based on the coupons association through f.deal_id
<% #freeCoupons.each do |f| %>
<%= #deals[f.deal_id][:title] %>
<% end %>
It gives me this error "undefined method `[]' for nil:NilClass". Not sure what I'm missing here. Is it a symbol problem that I'm missing? Any help would be appreciated.
In your Coupon model do
belongs_to :deal
Then in your controller, include the deals using includes - this will ensure you don't make an N+1 query:
#free_coupons = Coupon.includes(:deal).where(discount: 100).order("created_at DESC").page(params[:page])
Now in your view, you can simply call the deal method on a Coupon instance:
#free_coupons.each do |f|
<%= f.deal.title %>
end
deal_id is the id in the database, and it is NOT the index in the array. deal_id can be much bigger that the number of elements. Than you get a nil, and your error when you try to access the title
You find a Object by ID with
Deal.find(f.deal_id)
Related
I'm trying to render simple check_boxes in a list of results so users can select on which of these results to get additional content for.
Example model setup (names changed):
UserRequest has_one :response
Response has_many :individual_results
IndividualResult has_one :contact_info
In the UserRequestsController I have a show action, which shows the user_request (duh), response, and its individual_results in a table.
The user should be able to select items (= contact_info) to request additional content for those. For some reason I don't manage to render the check_boxes after days of trying. Basically, I don't really understand where and how to store the array of selected contact_infos and how to pass it to the method that then gets the additional content.
My attempt was:
Create a ContactInfosController (didn't exist before, the user was only creating and showing her requests up to now, so contact_info was "model only" before)
Create a method request_content(contact_infos) (as post, to pass the user-selected contact_infos to. If I were to make it Restful, it would probably be "edit/update")
Add the form with check_boxes search_request#show
My search_request/show.html.erb:
<tbody>
<% if #response %>
<% form_for #contact_infos, url: contact_infos_request_content_path(#contact_infos) do |form| %>
<% #response.individual_results.each do |result| %>
# result.foo, ...
# result.contact_info.bar
<%= form.check_box "contact_info", "contact_info.request_content?", "true", "false %>
<% end %>
# form.submit
<% end %>
<% end %>
</tbody>
As it didn't work, I also had to declare the instance variable #contact_infos in RequestsController#show as #contact_infos = #response.individual_results.map { |r| r.contact_info }
Now, it fails at the check_box with "undefined method `merge'". Also, not sure how the params would be passed? I feel I went seriously "off the rails" and probably screwed up the design with this as it seems way too complicated...
Would anybody be so kind and help me get into the right direction, e.g., how would you pass the response to a method to request additional information? Read tons online but somehow couldn't apply it.
Thanks so much!
The run down. A person can have many bids, this particular person only has one bid.
In my index action I have #bids = Bid.find_by_person_id(params[:person_id])
in my view I do
<% #bids.each do |bid| %>
<%= bid.bid_amount %>
<% end %>
I am getting NoMethodError: undefined method each' for #<Bid:0x007f988a346f00> when visting the index view for person bids.
Is this because this person only has one bid? I feel thats not the case, but other than that im at a loss..
find_by returns the first item. I think you are looking for
Bid.where(person_id: params[:person_id])
Austio's answer is correct.
However, why are you calling the Bid model directly?...
A person can have many bids
You're obviously constructing data from the person model, so why not call the following:
#person = Person.find params[:person_id]
#bids = #person.bids #-> bids belong to #person
This will build the collection without calling where.
Of course, your method only uses a single db query. But even still, the above is much more intuitive.
--
As an aside, you'll also want to use a conditional before your loop:
<% if #bids.any? %>
<% #bids.each.... %>
<% end %>
Having one bid is fine, but having none will cause the loop to spit out an error. The above resolves that issue.
I am having some trouble while looping some association:
#=> member.rb
has_one :academic
#=> academic.rb
belongs_to :member
So far so good. However, when I loop through the association, I get:
undefined method 'each' for #<Academic:0x007fc98b2b7210>
Here's my view (show):
<% if !#member.academic.nil? %>
<% fields_academic = [:major, :second_major, :minor, :second_minor] %>
<h1>Academics</h1>
<% #member.academic.each do |academic| %>
<%= render 'database/shared/display', model_obj: academic, data: academic, fields: fields_academic %>
<% end %>
<% end %>
The code is stuck at the each method.
#member is defined as = Member.find(params[:id])
Any help will be gladly appreciated. Thank you in advance!
According to your code there are no multiple instances of academic related to the given member (it's defined using has_one relation).
The answer is: you cannot loop them.
The correct code for your view should be:
<% if #member.academic.present? %>
<% fields_academic = [:major, :second_major, :minor, :second_minor] %>
<h1>Academics</h1>
<%= render 'database/shared/display', model_obj: #memeber.academic, data: academic, fields: fields_academic %>
<% end %>
<% end %>
If your intention was to have many academics for a memeber, then use has_many instead.
class Member
has_many :academics
end
each should be used on a collection of records( I mean which results in a multiple records). Currently #member.academic will return a single record as it is a has_one relation between member and academic, so you can't loop with that. May be you should change your association to has_many :academics and loop it like <% #member.academics.each do |academic| %>
Method :each iterates over the block according to how this Enumerable was constructed. If no block is given, returns self. Enumerable is a mixin that provides to collections some useful methods. In your example academic is a not Enumerable, but single object. You should use has_many association.
In a rails project, I use below code to retrieve data from Assignmenttable in database and show to user:
views/assignmenttables/_form.html.erb
<% task_list = Assignmenttable.find_by_current_user_id(user.id) %>
<% if task_list.blank? %>
<h1>It's blank</h1>
<% else %>
<% task_list.each do |task| %>
<%= task.id %>
<% end %>
<% end %>
data is retrive correctly from database, if task_list isn't empty this code is correct, but when task_list is empty, I get below error:
undefined method `each' for #<Assignmenttable:0x000000069541c8>
how can I handle this error?
The error you've got is caused because the object you called the .each method for is not a collection (multiple) - it's singular
Where
The way to fix this is to either use the .where method to call your data:
<%= task_list = Assignmenttable.where(user_id: current_user.id) %>
--
Associations
Or a better way will be to refactor your code to use the ActiveRecord associations which make Rails so appealing:
#app/models/user.rb
has_many :assignments
#app/models/assignment.rb # -> notice the name
belongs_to :user
current_user.assignments #-> allows you to call this in views
--
Model Names
Another thing you need to consider is your model names need to use CamelCase (AssignmentTable)
I have the following data architecture:
:tplangroups has_many :tplans
:tplans belongs_to :tplangroups
:tplans has attr_accessible :favrank
I need to get the id of the tplan with the highest favrank from each tplangroup, this routine below is how I'm trying to accomplish that:
<% #tplangroups.each_with_index do |tplangroup, index| %>
<% #highest_favrank = 0 %>
<% #highest_id = tplangroup.tplans[0] %>
<% tplangroup.tplans.each do |tplan| %>
<% if tplan.favrank >= #highest_favrank %>
<% #highest_favrank = tplan.favrank %>
<% #highest_id = tplan.id %>
<% end %>
<% end %>
#does stuff with tplangroup
<% end %>
However, I keep getting the following error:
undefined method `>=' for nil:NilClass
Any ideas? I really have no idea why it's throwing this error. I know that all of the attributes/variables I am referencing have values, I have tested this. I am not sure where I'm going wrong, thanks in advance!
The error message is pretty obvious: Your tplan.favrank is nil, and Ruby can't compare nil using >= to #highest_favrank.
You should remove nils from that array before you try to display it, using compact, or you should figure out why you are getting a nil.
Unfortunately, we can't tell you because you didn't supply code that shows how the values are created, nor is there data we can try to recreate your structure.
Maybe your table has nil values? Maybe your code is not trapping every condition, allowing nils to leak in.