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


1 answer


You have not received result["postings"]

in params

therefore result["postings"] = nil

and this creates a problem

Edit

result["postings"].each do |posting|
  #Your code here
end

      



to

result["postings"].each do |posting|
  #Your code here    
end if result["postings"]

      

+3


source







All Articles