Nil value for array in Rails 3 - ruby-on-rails

I feel like a moron asking this, but since I'm a new to developing, and I've been sitting here for an hour making something so simple work, I need to ask.
I want to show each Widget, but I keeping getting:
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.each
I tried using <%= debug #widgets %> and <%= #widgets.inspect %>, but nothing shows in my command prompt or browser.
I was trying to copy the each do statement on http://guides.rubyonrails.org/layouts_and_rendering.html
In my controller, called Pages Controller, I have:
def widgets_to_show
#widgets = Widget.all
end
In my view (pages#widgets_to_show), I have:
<% #widgets.each do |widget| %>
<%= widget.title %>
<% end %>
I have a widget model
I also have values in the widgets table
and I have a title field, so I'm not sure what I'm doing wrong
I'm trying to display it on a page that uses the High Voltage gem (https://github.com/thoughtbot/high_voltage) if that makes a difference.

As #DaveNewton suggested try accessing the widget from your console (not irb). Do the following from your terminal
# from your rails project dir
$ rails c
$ w = Widgets.all
$ puts w
$ w.each { |n| puts n.title }
If all of that works then we need more info to figure out what the problem is.
Edit:
My guess is that it has something to do with using high voltage on the same page. It's a gem for creating static pages so maybe that's interfering with showing your widgets - since what you're doing is something dynamic.

Related

Ruby Find last record value in has many

I'm trying to find the last Econ_Result that belongs to a Econ_Report. I want to display the last record of the Econ_Result (ordered by "release_date") for each Econ_Report on the index view. In the controller I tried to take the list of all reports and find the last result using the following:
#econ_reports = EconReport.all
if #econ_reports.econ_results.size >= 1
#last_result = #econ_report.econ_results.last.release_date
end
econ_report.econ_results.size works on the index view when I place it in for each loop. When I try to call the value of the last record I run into issues with the fact that some reports don't yet have results (a temporary issue) so I threw in the if then check in the controller which is currently failing.
Thanks in advance for the rookie help.
Since #econ_reports is a collection of EconReport objects, you can't call an instance method like .econ_results on it. Instead, you can only call it on instances within the collection:
#econ_reports.each do |econ_report|
if econ_report.econ_results.any?
last_result = econ_report.econ_results.last
end
end
However, this can be terribly inefficient for a large collection of #econ_reports: both lines with econ_report.econ_results will query the database separately, meaning that you'll query the database independently for each econ_report in the collection. This is known as the N+1 query problem.
Luckily for you, as discussed in the link, Rails has a built-in solution to optimize this code so you'll only query the database once:
<% #econ_reports.includes(:econ_results).each do |econ_report| %>
<% if econ_report.econ_results.any? %>
<% last_result = econ_report.econ_results.last %>
# do something to display last_result
<% end %>
<% end %>
If you just want the release date you might try:
#last_result = #econ_report.econ_results.order('release_date DESC').limit(1).pluck(:release_date).first
It's worth noting that a Ruby if statement generally looks like:
if condition
end
The then is almost always omitted even though it is allowed.

Ruby On Rails - "undefined method `id' for 4:Fixnum"

I recently decided I wanted to list all the users in my Ruby On Rails application - since I couldn't figure out how to list them any other way, I decided to use partials.
I have the following on my administration page (just hooked up to a its own administration controller):
<%= render :partial => User.find(:all) %>
I then have a file called _user.html.erb in my users view folder. This contains the following:
<ul>
<% div_for #user.object_id do %>
<li><%= link_to user.username, user.username %></li>
<% end %>
</ul>
When the application runs and I go to the administration page, I get the following error:
undefined method `id' for 4:Fixnum
It says it's because of this line (which is in the partial file):
<% div_for #user.object_id do %>
I'm unsure why this happens (and have googled for hours to try and find results and only find solutions that don't work for me). I think it's something to do with my usage of the #user instance variable, but I'm not totally sure.
You get that error because div_for expects an active record object as an argument, which it calls the id method on. You pass in a fixnum (the result of #user.object_id), which is not an active record object and does not have an id method.
So pass in #user instead of #user.object_id and it will work.
Also you should use user instead of #user, rails 3 does not set instance variables for partials anymore.
Lose the .object_id part. I seriously can't think why are you using object_id!Do you have a good reason for doing so? Anyway div_for wraps a div around an object, so leave the .object_id part!
instead of object you are using it's column or visa varsa you are using at that time you will get this kind of error.
Example
I am using id instead of user = User.first object.
Try this, it worked for me.
#item.unit_of_measure.name
instead of
#item.unit_of_measure_id.name

Rails - "can't convert Symbol into String" on Production ONLY

I have partial view that displays model-specific flash messages. The partial looks like:
app/views/mymodel/_flashpartial.erb
<% flash.each do |key, value| %>
<% if model_key = myModelFlash(key) then %>
<%= content_tag(:div, value, :class => "flash #{model_key}") %>
<% end %>
<% end %>
The myModelFlash method simply takes the key and checks for a particular prefix using a simple regex. It's located in
app/helpers/mymodelhelper.rb
module MyModelHelper
def myModelFlash( key )
m = /^_mymodel_(.*)/.match(key)
m[1] unless m.nil?
end
end
This works perfectly fine in my development and test environments. As soon as it goes onto Heroku, I get an error saying (ActionView::Template::Error) "can't convert Symbol into String" pointing to the call to match.
If I remove the call to myModelFlash from the view and simply display the key and value, that works just fine in terms of not erroring out, so at the very least the key and value are getting into the partial view just fine. For some reason the helper method thinks that the key being passed into it is a symbol and not a String.
Any ideas as to why this might be happening?
I suggest you just use key.to_s as a quick workaround.
The reason for your problem may be that some version of some component differs between your testing server and the production server.
If your tests pass, and your production environment crashes, that is a very bad situation.
You should compare the versions of ruby and all of the gems you are using. If you use 'bundler' then 'bundle list' gives a nice summary.
If you find out that all the versions are the same... Well, we will be looking for another reason.
Update
As it seems that the problem is caused not by the version differences, but by unexpected data in flash, which obviously in production environment may be different than in testing.
I suggest you change the myModelFlash method a little.
def myModelFlash( key )
if m = /^_mymodel_(.*)/.match(key.to_s)
return m[1]
end
end
The flash may contain different keys, some of them may be Symbols or really anything, so you must be prepared to handle all of them.
Converting the key parameter with .to_s should be a safe choice, but if you are sure that you always set the flash keys (I mean the keys related to this "_mymodel" issue) as Strings, you may change the first line of this method:
def myModelFlash( key )
if key.is_a?(String) && m = /^_mymodel_(.*)/.match(key.to_s)
return m[1]
end
end
And in your test, add a few other keys to your flash, and then test how the action handles them.

rails comparing values of params[:id] and session[:user_id] not working

I'm new to rails after moving from PHP and am having no end to the frustrations, but hopefully there is a steep learning curve.
I was following a guide on how to make a twitter clone in rails, and have continued along that path making it more and more twitter like.
So I've got a 'users' page /users/show.html.erb which show all the posts from a user.
Now, if the currently logged in user is the same as the page owner, I'm trying to show the text box so that the user can add a new entry.
I've got what should be a very simple
<% if params[:id] == session[:user_id] %>
put the text box here
<% end %>
of course, that isn't working, but right above it I've output both the session[:user_id] and the params[:id], and the printout is exactly the same.
If I set the == to !=, I get the 'put the text box here' message.
any suggestions as to what I'm doing wrong?
I know these two values match, as I can see in the url and the output of the currently logged-in user. I've also output
-<% session[:user_id] %>-
-<% params[:id] %>-
so that I can see there is no gaps or spaces or other characters on either end of the parameters, and it all looks clean.
The output looks like this
-4c4483ae15a7900fcc000003-
-4c4483ae15a7900fcc000003-
which is the mongodb objectId of the user with dashes on either side to show that there are no spaces or anything.
Are you sure that both items are simple strings? What happens if you run, say
params[:id].to_s == session[:user_id].to_s
?
It could be like jasonpgignac pointed out. If you enter into IRB:
num = "7"
num2 = 7
num == num2 # => false
Make sure they are both of the same type. Putting <%= num2 %> will actually trigger the .to_s method... hence why the two appear to be equal when you output them in your .erb page.
Also, you might want to move that comparison into the controller. Something like:
#is_user_home = params[:id].to_s == session[:user_id].to_s
Then you can put in your view:
<% if #is_user_home %>
code here
<% end %>
It makes the code a little more easier to read.
As it was already stated, in most cases this kind of problems are caused by mismatch of compared types. Just adding to_s to both variables solves most cases.
Here check great source to learn more about all kind of comparisons used in Ruby.

Rendering a variable with erb

I've got the following problem: I have rhtml (html minced together with ruby inside <% %> and <%= %> tags) stored in a database which I want to render. The information is acquired through a query. I need to be able to evaluate the information I get from the database as though as it was normal content inside the .erb-file. What I currently have:
<% #mymods.each do |mod| %>
<%= render_text(mod["html"])%>
<% end %>
Where mod["html"] is the variable containing the rhtml-code and #mymods an array of objects from the query. I have currently no idea what function I should use (render_text does, of course, not work).
Help is greatly appreciated.
/TZer0
You can use the ERB object to render text without the text being in a file.
Just pass the text with the <%= %> tags. You could put something like the following as an application_helper function.
def render_erb_text(text, args={})
b = binding
template = ERB.new(text, 0, "%<>")
template.result(b)
end
And then in your template
<%= render_erb_text("<%= %w(hi how are you).join(' - ') %>")%>
You might also consider rendering the text in your controller as you can handle any render errors better there than during view evaluation.
Take a look at the ERB documentation for more information regarding variable binding etc.
I'm not familiar with the details of how this works under the covers, but there could be some serious risk in running this code on bad or malicious database data. Evaluating ruby code from user input or any un-vetted source should be done very carefully, if at all.

Resources