NoMethodError in Posts#new - ruby-on-rails-3.1

I'm doing the Getting started with Rails tutorial and when I run the local server from shell I get this:
`NoMethodError in Posts#new` `/_form.html.erb where line #1 raised:
`undefined method `model_name' for NilClass:Class
That is the extracted source (around line #1):
1: <%= form_for #post do |f| %>
2: <% if #post.errors.any? %>
3: <div id="errorExplanation">
4: <h2><%= pluralize(#post.errors.count, "error") %> prohibited
I just started on Ruby on Rails and I can't figure out what is happening. What am I doing wrong?

The error message, you are seeing means that you have some variable that contains a nil object instead of the actual object you expect.
While the error message doesn't explicitly reference this, it is likely your #post variable is nil.
Why is it nil? That's near impossible to say given the code here. Please post your PostsController#new action as well.

The fix is into posts_controller.rb, add next code
def new
#post = Post.new
end
Good luck

// Make sure to use model declaration inside your method to check the error logs
class PostsController < ApplicationController
def new
#post = Post.new
end

Related

undefined method `each' for nil:NilClass -- again-- i dont get it. Constantly getting this error

class ProfileController < ApplicationController
def show
#user = current_user
#first_name = #user.first_name
#last_name = #user.last_name
end
def settings
end
def pics
#photos = current_user.photos.all
end
end
in the view of _pics.html.erb, I have
<% #photos.each do |p| %>
<%= image_tag p.image(:medium) %>
<% end %>
If I change it to current_user.photos.each do |p|, it works, which is weird. I don't get an error from this code on my other computer.
In a comment you said, that you render the pics partial from your show view. Since the show view is rendered by the show action and the show action does not set the #photos variable, you can't use that variable. So to fix your problem, you'd need to set the variable in the show action.
You seem to think that rendering the pics partial will invoke the pics action, but that's not the case. An action will only be invoked if an URL is accessed that's mapped to that using the routing system. Rendering partials does not invoke any actions.
Also it should just be #photos = current_user.photos without the all.

how to connect to Twilio API with ruby

Sorry this is a very basic question so it should be easy to answer!
Using ruby and sinatra, I am trying to connect, via the api, to get details of my calls. The prescribed way to do this by twilio seems to be:
#client = Twilio::REST::Client.new account_sid, auth_token
# Loop over calls and print out a property for each one
#client.account.calls.list.each do |call|
puts call.sid
puts call.from
puts call.to
which works fine and "puts" the data in the terminal. I want to print the results on an HTML page, so I changed the line
#client.account.calls.list.each do |call|
to
#calls = #client.account.calls.list
and removed the last 3 lines of the code block above, ie. all the "puts"
then, attempting to print on my index page I included the following:
<% #calls.each do |call| %>
<h4 style="color: #ff0000;"><%= params['msg'] %></h4>
<ul>
<li> <%= call.from %> </li>
<li> <%= call.to %> </li>
</ul>
<% end %>
The error message says:
undefined method `each' for nil:NilClass
so I am not connecting to twilio it seems even though the code is almost exactly the same as that above which does connect and produce the required results.
Any ideas? All help gratefully received.
In Sinatra, do not use instance variables to store connection objects and similar stuff. Instead of #call, use the set method that enables a user to set such objects to different variables.
The calls.list method, as per the code, is defined in the Twilio::REST::ListResource module. This returns an array and so, the second part of your code (in the index.erb) is correct.
The problem is, when you start using instance variables for storing the connection object, it gets reset in the route and that's what's happening inside the get do .. end block.
Change the code to:
set :client, Twilio::REST::Client.new(account_sid, account_pass)
# Now, this setting can be accessed by settings.client
get '/calls' do
#calls = settings.client.account.calls
erb :index
end
# index.erb
<% #calls.each do |call| %>
...
<% end %>
This should work.

String will work but not symbols in Rails

To learn Rails, I am writing a simple guestbook app that does not use a database.
Anyway, this is what my view looks like:
views/guest_book_pages/home.html.erb
<h1>Guest Book</h1>
<%= #userinput %>
<%= form_for(:guestbook) do |f| %>
<%= f.label :input %>
<%= f.text_field :input %>
<%= f.submit "Sign" %>
<% end %>
And the controller looks like this:
controllers/guest_book_pages_controller.rb
class StaticPagesController < ApplicationController
def home
#userinput = params[:guestbook]["input"]
end
end
Whenever I change the "input" to a symbol :input, the application breaks and gives me a warning that says: undefined method `[]' for nil:NilClass
What is the reason for this? Why can't I use a symbol?
update: Now it won't even work with the string. What is going on?
update#2: It works with both symbols and string. The only problem is that it will not load the first time. If I can get the page to load, then either will work. How can I get the page to load?
Action use to be handle something, and render view.
when you inter home, the home action has be called, and no param posted now.
for your code, home action should just be empty, it just to render the home_page.
your handle code should move to some action like sign_in, whitch handle the form post and you can get the params.
The first time you load the page the params var is not set. It is only when you submit your form back that there are params
Try
#userinput = params[:guestbook]["input"] || ''
which will initialize the #userinput to an empty string if the params is not found
edit:
This will check if the params has the key guestbook first, then will either set the instance var userinput to an empty string or the value of [guestbook][input] if it exsists.
If all else fails, the instance var is initialized to an empty string to prevent an error in your view.
if params.has_key?(:guestbook)
#userinput = params[:guestbook]["input"] || ''
else
#userinput = ''
end

DataMapper fetching last record using .last throws no method error if using .any? in view

Apologies for the long wined title, in my app I am trying to retrive e the last record from the database that matches the params I have passed to it.
#goals = Weight.last(:is_goal=>true,:user_id=>#user.id)
In my views I want to run a conditional that checks if there are any present and if it has it will display a div.
<% if #goals.any? %>
<% #goals.each do |goal| %>
<p><%= goal.amount %></p>
<% end %>
<% end %>
But for some reason this throws a no method error NoMethodError at /
undefined method 'any?'. If I change the .last to .all it works
#goals = Weight.all(:is_goal=>true,:user_id=>#user.id)
Is there any reason behind this or have I found a bug?
Well, .last method returns an object, .all method returns an array of objects.
And .any? is an array method. You can't call .any? on an object, it will tell you that there is no method unless you have created one.

How to upload a file temporarily in Rails 3?

I'm creating CSV-upload functionality for a site of mine.
I'm looking to upload a file, parse it, and then dispose of it.
I know I can upload and save a file using Paperclip, but that seems a bit like overkill.
All I need to do is parse the uploaded file and never save it.
How would I go about doing this in Rails 3?
Note: I'd prefer to do the uploading manually without using an external gem so I can learn how to process works, but any suggestions are welcome.
Thanks!
Use the file_field helper in your form, then in your controller you can use File.Write and File.read to save the file.
E.g. View
<%= form_for #ticket do |f| %>
<%= f.file_field :uploaded_file %>
<% end %>
Controller
def upload
uploaded = params[:ticket][:uploaded_file]
File.open(<insert_filename_here>, 'w') do |file|
file.write(uploaded.read)
end
end
Edit: Just saw #klochner's comment, that link says pretty much what I have said so follow that: RubyOnRails Guides: Uploading Files.
Paste this in your model
def parse_file
File.open(uploaded/file/path, 'w') do |f| # Feed path that user gives in some way
## Parse here
end
end
this in view
<%=form_for #page, :multipart => true do |f|%>
<ul><li><%= f.label :file%></li>
<li><%= f.file_field :uploaded_file%></li></ul>
<%end%>
Let me know if this works. If it fails figure out a way to feed path of uploaded_file in parse_file method (the definite way which will work is storing file location in db and picking up from there, but it is not the right way to do this thing). Otherwise, I guess it should work.
Complete Example
Take, for example, uploading an import file containing contacts. You don't need to store this import file, just process it and discard it.
Routes
routes.rb
resources :contacts do
collection do
get 'import/new', to: :new_import # import_new_contacts_path
post :import, on: :collection # import_contacts_path
end
end
Form
views/contacts/new_import.html.erb
<%= form_for #contacts, url: import_contacts_path, html: { multipart: true } do |f| %>
<%= f.file_field :import_file %>
<% end %>
Controller
controllers/contacts_controller.rb
def new_import
end
def import
begin
Contact.import( params[:contacts][:import_file] )
flash[:success] = "<strong>Contacts Imported!</strong>"
redirect_to contacts_path
rescue => exception
flash[:error] = "There was a problem importing that contacts file.<br>
<strong>#{exception.message}</strong><br>"
redirect_to import_new_contacts_path
end
end
Contact Model
models/contact.rb
def import import_file
File.foreach( import_file.path ).with_index do |line, index|
# Process each line.
# For any errors just raise an error with a message like this:
# raise "There is a duplicate in row #{index + 1}."
# And your controller will redirect the user and show a flash message.
end
end

Resources