if/else in erb executing code it should not - ruby-on-rails

Thanks to everyone for providing me with information! There were some very quick responses. My solution was to use a clearer test in the if. Grammar for the win!
"You have a nil object when you didn't expect it! The error occurred while evaluating nil.name"
This error points to the line below with "file.name".
I get why it evaluates to nil.name and is empty(it should be) but I don't understand why that code is even executed.
It works by changing the test for if to..
if file[0] != nil
I feel like there's an important detail I'm missing so I'd appreciate some help with understanding this.
In my view I have:
<table>
<tr>
<th>File</th>
<th>Description</th>
</tr>
<% if !#files.empty? %>
<% #files.each do |file| %>
<tr>
<td><%= file.name %></td>
<td><%= file.description %></td>
<td><%= link_to "Download", :controller => "files", :action => "download", :id => file.id %></td>
<td><%= button_to "Delete", { :controller => "files", :action => "destroy", :id => file.id }, :method => "delete" %></td>
</tr>
<% end %>
<% else %>
<tr>
<td><b>No files</b></td>
</tr>
<% end %>
</table>
In the controller I create an empty array called #files and then push in values later when they're created.
Ruby 1.8.7-p72
Rails 2.2.2

What you want in your #files instance var is either an empty array
#files = []
or actual File objects
#files = File.all
but you seem to somehow produce an array that contains nil elements, for example
#files = [nil, <#File>, <#File>]
so #files itself is not nil, while its first element is. Therefore, the following code returns true
#files.any?
which is equivalent to
!#files.empty?
because #files.is_a? Array and not #files.nil?. Your problem must be in the corresponding controller, where you seem to add a nil element to your #files.

Related

Rails Access Association attributes issue

I have an html table that renders a partial as follows
<tbody id="horse_logs">
<%= render #horse_logs %>
</tbody>
This calls _horse_log.html.erb and iterates through each element in #horse_logs
<tr id="<%= dom_id(horse_log) %>">
<td><%= horse_log.id %></td>
<td><%= horse_log.name %></td>
<td><%= horse_log.boarder.first_name%></td> <!-- This is the association I want to access -->
<td><%= horse_log.arrival_date %></td>
<td><%= horse_log.monthly_boarding_fee %></td>
<td><%= link_to '<i class="link blue large id card icon"></i>'.html_safe, horse_log_path(horse_log)%></td>
<td><%= link_to '<i class="link green large edit icon"></i>'.html_safe, edit_horse_log_path(horse_log), remote: true %></td>
<td><%= link_to '<i class="link red large remove icon"></i>'.html_safe, horse_log_path(horse_log), method: :delete, :data => {:confirm => 'Are you sure?'}, remote: true %></td>
</tr>
The issue is that accessing the boarder association inside the partial gives the following error
undefined method `first_name' for nil:NilClass
So basically the way rails implements this, they seem to be stripping the association data. The association is set up in my models correctly, and I can access the data in all other ways EXCEPT inside the partial.
How can I force rails to include the entire association.
here is my controller method if this helps
def index
#horse_logs = HorseLog.all.paginate(:page => params[:page], :per_page => 9).order("created_at DESC")
#horse_log = HorseLog.new
end
There may be a better way to do this but I would try.
<tbody id="horse_logs">
<% #horse_log.each do |horse_log| %>
<%= render 'horse_logs', horse_log: horse_log %>
<% end %>
</tbody>
If you get the same error, then you will need to make sure that your association is set up correctly.
Does every horse_log have a boarder? If not, you will get this error every time you run this code. you will need to check that hourse_log.boarder isn't nil.
For a quick fix, try this. It will prevent the error and return nil gracefully
<td><%= horse_log.try(&:boarder).try(&:first_name) %></td>

Pass .each loop reference object in Ruby on Rails

I am writing a code in ruby on rails where I am creating dynamic rows in table which involves a .each loop. I want to pass the .each loop reference object but it gives me an error.
Following is the code:
<% pworkflows.workflow_executions_list.each do |wf| %>
<tr>
<td><%= wf.execution_status %></td>
<td>
<% if(wf.start_timestamp != nil) %>
<%= wf.start_timestamp.localtime; %> UTC
<% end %>
</td>
<td><%= wf.close_status %></td>
<td><%= wf.execution.run_id %></td>
<td><%= button_to "Details",{ :controller => "pages", :action => "mainpage",:rulesetinstance=>rInsId, :ndetails=>wf} %></td>
</tr>
<% end %>
:ndetails=>wf gives an error. wf is not being recognized as a correct syntax to send.
Please suggest a way.
the error being:
undefined local variable or method `id' for #<ComRuleManagement::WorkflowExecutionObject:0x00003da1751528>
When you do this
<%= button_to "Details",{ :controller => "pages", :action => "mainpage",:rulesetinstance=>rInsId, :ndetails=>wf} %>
you are building an html tag. (since button_to is an html helper). The extra options you pass through, in this instance ":rulesetinstance" and ":ndetails" will be used to make extra attributes in the element, like rulesetinstance="123". However, if you pass the wf object through, then rails will call to_s on it, and you'll end up with something that looks like this ndetails="#<Wf:0x7f518dfc6e68>". This is almost certainly not what you want in your html element. Should you be calling another method of the wf object instead?

Editing Quantity in Cart

So this is another post about updating the quantity in the cart! Any one that I could find seemed to be outdated, so I apologize if this seems repetative.
But I am following along in Agile Web Development with Rails 4th edition book, and they were so kind as to leave editing the quantity as a 'challenge' and not show the answer :D. Now as I'm trying to get it to work I'm having troubles.
Show in my views/cart/show.html.erb I have the following table
<table>
<tr>
<th>Quantity</th>
<th>Product Name</th>
<th>Size</th>
<th>Price</th>
</tr>
<% #cart.line_items.each do |item| %>
<tr>
<td>
<%= form_for 'item', :url => {:controller => 'line_items', :action => 'update', id: item} do |f| %>
<div class="field">
<%= f.number_field :qty, :value => item.qty %>
<%= submit_tag "Update" %>
</div>
<% end %>
</td>
<td><%= item.product.name %></td>
<td><%= item.size %></td>
<td><%= number_to_currency(item.total_price) %></td>
</tr>
<% end %>
<tr>
<td colspan="3">Total Price</td>
<td><%= number_to_currency(#cart.total_price) %></td>
</tr>
</table>
Yet when I click update I get either
Unknown action
The action '29' could not be found for LineItemsController
or
Unknown action
The action '35' could not be found for LineItemsController
even if I completely take out the id field. I can deal with the update function on the controller side and getting it update properly - I want to figure that out on my own but I can't figure out what could possibly be generating these numeric actions and how I can fix it. In short, what is producing this error and how can I fix it? Is it perhaps related to the fact I have a line_item form in a cart view?
do you check the 29 and 35 is either ur id or anything else? try to check with your database for LineItems , and how your controller look like?? and
<%= form_for 'item', :url => {:controller => 'line_items', :action => 'update', id: item} do |f| %>
you trying to update it in ajax way or ? when update the quantity, should it be using ajax if it's not mistaken (the book asked to do in that way right? )
So I got it working - that I did was I tweaked the form header like so
<%= form_for :item, :url => line_items_update_path(id: item.id) do |f| %>
I added the following line to my routes.rb
get "line_items/update"
And added one line to my line_items_controller
def update
#line_item = LineItem.find(params[:id])
#line_item.qty = params[:item][:qty] #added this line here
For those who are having problems!

Rails RuntimeError: "Called id for nil". Rails is telling me that the instance variable I'm passing in through params[:id] is null [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
EDIT2: [SOLVED] The "create" method in the controller file does not "end" until after the "edit" method. I can't answer my own question until 8 hours afterwards, however.
EDIT: It's been brought to my attention that this may be a problem with my routes.rb file. Which is just below.
routes.rb
SimpleCms::Application.routes.draw do
root :to => "subjects#list"
match ':controller(/:action(/:id))(.:format)'
end
Essentially this is an #instance_variable issue. More specifically an #instance_variable[:id => nil] problem. Somehow I'm passing a nil (null) :id (primary key) value to rails but the edit button which I'm clicking on (the last file in this list is the list.html.erb file which contains the button that takes you to edit.html.erb) is supposed to be passing the :id value corresponding to the given subject on the list page.
So here is the error message from the browser first of all:
RuntimeError in Subjects#edit
Showing C:/Users/davo/Desktop/RailsProjects/simple_cms/app/views/subjects/edit.html.erb where line #6 raised:
Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
Extracted source (around line #6):
3: <div class="subject edit">
4: <h2>Update Subject</h2>
5:
6: <%= form_for(:subject, :url => {:action => 'update', :id => #subject.id}) do |f| %>
7:
8: <table summary="Subject form fields">
9: <tr>
Rails.root: C:/Users/davo/Desktop/RailsProjects/simple_cms
Application Trace | Framework Trace | Full Trace
app/views/subjects/edit.html.erb:6:in `_app_views_subjects_edit_html_erb__829468061_51428148'
Request
Parameters:
{"id"=>"1"}
Here is the controller ("subjects_controller.rb") so you can see the instance variable stuff. The edit and update methods are on the bottom
**All the other methods which call params[:id] are working. It's possible that there is nothing wrong with the controller and that it's just the view. In particular, on that view, the #subject versus :subject versus subjects.method stuff...there seems to be something wrong with that syntax.
class SubjectsController < ApplicationController
def list
#subjects = Subject.order("subjects.position ASC")
end
def index
list
render('list')
end
def show
#subject = Subject.find(params[:id])
end
def new
#subject = Subject.new(:name => 'default')
end
def create
#instantiate a new object using form params
#subject = Subject.new(params[:subject])
#save the subject
if #subject.save
redirect_to(:action => 'list')
#if save succeeds redirect to list action
else
#if save fails, redisplay form
render('new')
end
def edit
#subject = Subject.find(params[:id])
end
#passing an #instancevariable inside of a {hash}...is there anything odd about that?
#I'm just trying to inspire you guys -->
#
#I have a hunch that the :syntax/#syntax/#{etc} involving params, :id and
#:subject could be the root of this issue...just a hunch
#
def update
#Find object using form parameters
#subject = Subject.find(params[:id])
#Update the object
if #subject.update_attributes(params[:subject])
redirect_to(:action => 'show', :id => #subject.id)
else
render('edit')
end
end
end
end
Lastly, here is edit.html.erb
<%= link_to("<< Back to List", {:action => 'list'}, :class => 'back-link') %>
<div class="subject edit">
<h2>Update Subject</h2>
<%= form_for(:subject, :url => {:action => 'update', :id => #subject.id}) do |f| %>
<table summary="Subject form fields">
<tr>
<th>Name</th>
<td><%= f.text_field(:name) %></td>
</tr>
<tr>
<th>Position</th>
<td><%= f.text_field(:position) %></td>
</tr>
<tr>
<th>Visible</th>
<td><%= f.text_field(:visible) %></td>
</tr>
</table>
<tr>
<td><%= f.submit 'Update Subject' %></td>
</tr>
<% end %>
</div>
EDIT:
here is the list.html.erb file, which contains the link that points to the edit.html.erb file, which, currently, does not open and displays the error message.
<html>
<div class="subject list">
<h2>Subjects</h2>
<!--- header row with all the different attributes --->
<table class="listing" summary="Subject list">
<tr class="header">
<th>#</th>
<th>Subject</th>
<th>Visible</th>
<th>Pages</th>
<th>Actions</th>
</tr>
<!-- this is the beginning of a loop, that ends way down there -->
<% #subjects.each do |subject| %>
<tr>
<td><%= subject.position %></td>
<td><%= subject.name %></td>
<td class="center"><%= subject.visible ? 'Yes' : 'No' %></td>
<td class="center"><%= subject.pages.size %></td>
<td class="actions">
<%= link_to("Show", {:action => 'show', :id => subject.id}, :class => 'action show') %>
<%= link_to("Edit", {:action => 'edit', :id => subject.id}, :class => 'action edit') %>
<%= link_to("Delete", '#', :class => 'action delete') %>
</td>
<% end %>
</tr>
</table>
<%= button_to "Create New Subject", {:action => 'new'}, {:class => "buttonTo"} %>
</div>
</html>
EDIT:
- Let me know if you need to see a particular model.rb file. In my models folder I have "subject.rb", "section.rb", "section_edit.rb", "page.rb" and "admin_user.rb" if you need to see any of those. I'm kind of stumped on this one so maybe they'd be useful. They all contain a bunch of schema (has_many, belongs_to, etc) instructions and a few custom console calls.
= form_for(#subject, :as => :subject, .....
#subject is not nil, because find raises exception if no record have been found
I made a typo when doing the some of the def/end syntax in the controller. I think it was 'def create', I didn't end it.

Rails 3 , Simple search form problem

Code in my product model (product.rb):
def self.search(search)
if search
find(:all)
else
find(:all)
end
end
Code in my search controller (search_controller.rb):
def index
#products = Product.search("Apple")
end
Code in my view (index.html.erb):
<h1>Products</h1>
<% form_tag client_search_path , :method => :get do %>
<p>
<%= search_field_tag :term, params[:term], :class=> "auto_search_complete"%>
<%= submit_tag "Search", :name => nil, :class => 'button', :id => "search_bn" %>
</p>
<% end %>
<table border="1px">
<tr>
<th>Name</th>
<th>Brand</th>
<th>Quantity available</th>
<th>Category</th>
<th>Shopcenter name</th>
<th>Shopcenter streetnumb</th>
<th>Shopcenter streetname</th>
<th>Shopcenter postal</th>
<th>Shopcenter province</th>
</tr>
<% for product in #products%>
<tr>
<td><%= product.name %></td>
<td><%= product.brand %></td>
<td><%= product.quantity_available %></td>
<td><%= product.category %></td>
<td><%= product.shopCenter_name %></td>
<td><%= product.shopCenter_streetNumb %></td>
<td><%= product.shopCenter_streetName %></td>
<td><%= product.shopCenter_postal %></td>
<td><%= product.shopCenter_province %></td>
</tr>
<% end %>
</table>
I load this all is good, but if I comment one of the line of codes in my model:
def self.search(search)
if search
#find(:all)
else
find(:all)
end
end
I expect this to work also at least for the initial render, or when I submit an empty search term, but it's not. And changing the code to of the model to:
def self.search(search)
if search
find_all_by_name(search)
else
find(:all)
end
end
Doesn't work it gives me an error that the view is working with a nil object, which is impossible because my database has entries.
Can someone explain what is going on? I have the impression that both the conditions in my model are being executed. At least that's what 2 puts statement in each case showed me.
Please advice.
I think you should set search = nil if search == "" in your controller otherwise it will always go to the first condition.
It had some compatibility issues with Rails 3.
I updated rails and ruby and it works fine now

Resources