Rails 4: NoMethodError: undefined `each 'method for nil: NilClass
Trying to copy the details of an apartment from Craigslist. Using 3taps api. It works, but I want to show the specific details of the apartment. I run a scraper: I scratch and get an error. NoMethodError: undefined method `each 'for nil: NilClass
I ran scraper: scrape -trace and get the following information
** Invoke scraper:scrape (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute scraper:scrape
rake aborted!
NoMethodError: undefined method `each' for nil:NilClass
/Users/neilpatel/Desktop/Rails/craigslist_scraper/lib/tasks/scraper.rake:33:in `block (2 levels) in <top (required)>'
/usr/local/rvm/gems/ruby-2.0.0-p247/gems/rake-10.4.0/lib/rake/task.rb:240:in `call'
/usr/local/rvm/gems/ruby-2.0.0-p247/gems/rake-10.4.0/lib/rake/task.rb:240:in `block in execute'
/usr/local/rvm/gems/ruby-2.0.0-p247/gems/rake-10.4.0/lib/rake/task.rb:235:in `each'
/usr/local/rvm/gems/ruby-2.0.0-p247/gems/rake-10.4.0/lib/rake/task.rb:235:in `execute'
/usr/local/rvm/gems/ruby-2.0.0-p247/gems/rake-10.4.0/lib/rake/task.rb:179:in `block in invoke_with_call_chain'
/usr/local/rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:211:in `mon_synchronize'
/usr/local/rvm/gems/ruby-2.0.0-p247/gems/rake-10.4.0/lib/rake/task.rb:172:in `invoke_with_call_chain'
/usr/local/rvm/gems/ruby-2.0.0-p247/gems/rake-10.4.0/lib/rake/task.rb:165:in `invoke'
/usr/local/rvm/gems/ruby-2.0.0-p247/gems/rake-10.4.0/lib/rake/application.rb:156:in `invoke_task'
/usr/local/rvm/gems/ruby-2.0.0-p247/gems/rake-10.4.0/lib/rake/application.rb:112:in `block (2 levels) in top_level'
/usr/local/rvm/gems/ruby-2.0.0-p247/gems/rake-10.4.0/lib/rake/application.rb:112:in `each'
/usr/local/rvm/gems/ruby-2.0.0-p247/gems/rake-10.4.0/lib/rake/application.rb:112:in `block in top_level'
/usr/local/rvm/gems/ruby-2.0.0-p247/gems/rake-10.4.0/lib/rake/application.rb:121:in `run_with_threads'
/usr/local/rvm/gems/ruby-2.0.0-p247/gems/rake-10.4.0/lib/rake/application.rb:106:in `top_level'
/usr/local/rvm/gems/ruby-2.0.0-p247/gems/rake-10.4.0/lib/rake/application.rb:84:in `block in run'
/usr/local/rvm/gems/ruby-2.0.0-p247/gems/rake-10.4.0/lib/rake/application.rb:182:in `standard_exception_handling'
/usr/local/rvm/gems/ruby-2.0.0-p247/gems/rake-10.4.0/lib/rake/application.rb:79:in `run'
/usr/local/rvm/gems/ruby-2.0.0-p247/gems/rake-10.4.0/bin/rake:33:in `<top (required)>'
/usr/local/rvm/gems/ruby-2.0.0-p247/bin/rake:23:in `load'
/usr/local/rvm/gems/ruby-2.0.0-p247/bin/rake:23:in `<main>'
Tasks: TOP => scraper:scrape
I have checked the code but cannot find a solution
lib / tasks / scraper
namespace :scraper do
desc "fetch Craiglist posts from 3taps"
task scrape: :environment do
require 'open-uri'
require 'json'
# Set API token and URL
auth_token = "fa9504f4383a477xxxxxxxx1cc86e0d"
polling_url = "http://polling.3taps.com/poll"
# specify request parameters
params = {
auth_token: auth_token,
anchor: 1503713374,
source: "CRAIG",
category_group: "RRRR",
category: "RHFR",
'location.city' => "USA-NYM-BRL",
retvals: "location,external_url,heading,body,timestamp,price,images,annotations"
}
# Prepare API requests
uri = URI.parse(polling_url)
uri.query = URI.encode_www_form(params)
# Submit Request
result = JSON.parse(open(uri).read)
# Store results in database
result["postings"].each do |posting|
#Create new Post
@post = Post.new
@post.heading = posting["heading"]
@post.body = posting["body"]
@post.price = posting["price"]
@post.neighborhood = posting["location"]["locality"]
@post.external_url = posting["external_url"]
@post.timestamp = posting["timestamp"]
@post.bedrooms = posting["annotations"]["bedrooms"] if posting["annotations"]["bedrooms"].present?
@post.bathrooms = posting["annotations"]["bathrooms"] if posting["annotations"]["bathrooms"].present?
@post.sqft = posting["annotations"]["sqft"] if posting["annotations"]["sqft"].present?
@post.cats = posting["annotations"]["cats"] if posting["annotations"]["cats"].present?
@post.dogs = posting["annotations"]["dogs"] if posting["annotations"]["dogs"].present?
@post.w_d_in_unit = posting["annotations"]["w_d_in_unit"] if posting["annotations"]["w_d_in_unit"].present?
@post.street_parking = posting["annotations"]["street_parking"] if posting["annotations"]["street_parking"].present?
# Save post
@post.save
end
end
desc "Destroy all posting data"
task destroy_all_posts: :environment do
Post.destroy_all
end
end
posts controller.rb
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
# GET /posts
# GET /posts.json
def index
@posts = Post.all.paginate(:page => params[:page], :per_page => 30)
end
# GET /posts/1
# GET /posts/1.json
def show
end
# GET /posts/new
def new
@post = Post.new
end
# GET /posts/1/edit
def edit
end
# POST /posts
# POST /posts.json
def create
@post = Post.new(post_params)
respond_to do |format|
if @post.save
format.html { redirect_to @post, notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: @post }
else
format.html { render :new }
format.json { render json: @post.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /posts/1
# PATCH/PUT /posts/1.json
def update
respond_to do |format|
if @post.update(post_params)
format.html { redirect_to @post, notice: 'Post was successfully updated.' }
format.json { render :show, status: :ok, location: @post }
else
format.html { render :edit }
format.json { render json: @post.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
@post.destroy
respond_to do |format|
format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
@post = Post.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def post_params
params.require(:post).permit(:heading, :body, :price, :neighborhood, :external_url, :timestamp)
end
end
db migrate file
class CreatePosts < ActiveRecord::Migration
def change
create_table :posts do |t|
t.string :heading
t.text :body
t.decimal :price
t.string :neighborhood
t.string :external_url
t.string :timestamp
t.timestamps
end
end
end
Add fields to message file
class AddFieldsToPosts < ActiveRecord::Migration
def change
add_column :posts, :bedrooms, :integer
add_column :posts, :bathrooms, :decimal
add_column :posts, :sqft, :integer
add_column :posts, :cats, :string
add_column :posts, :dogs, :string
add_column :posts, :w_d_in_unit, :string
add_column :posts, :street_parking, :string
end
end
index.html.erb
<table class="table table-hover table-condensed">
<thead>
<tr>
<th>Heading</th>
<th>Price</th>
<th>Beds</th>
<th>Baths</th>
<th>Neighborhood</th>
<th>Last Updated</th>
</tr>
</thead>
<tbody>
<% @posts.each do |post| %>
<tr>
<td><%= link_to post.heading, post%></td>
<td><%= number_to_currency(post.price,precision: 0) %></td>
<td><%= post.bedrooms %></td>
<td><%= post.bathrooms %></td>
<td><%= post.neighborhood %></td>
<td><%= "#{time_ago_in_words(Time.at(post.timestamp.to_i))} ago" %></td>
</tr>
<% end %>
</tbody>
</table>
<%= will_paginate @posts, renderer: BootstrapPagination::Rails %> %>
<br>
<%= link_to 'New Post', new_post_path %>
</div>
+3
source to share