Jon Poehlman
Jon Poehlman

Reputation: 25

#<NoMethodError: undefined method `any?' for nil:NilClass>

I am trying to build a simple app using datamapper with multiple data models. At one time, I it working were I had a parent and a child model that were associated. However, I have messed something up and cannot get one of my two models to work. I will the simplified code I am using to just try and see if the second model(called Songs) is working. The routes for the model titled Soundtrack work.

This is my first time posting, so apologize in advance if I have not shared enough. Just let me know and I will add more.

Jon

Model and Routes:

require 'data_mapper'
require 'dm-timestamps'

#models

configure :development do
  DataMapper.setup(:default, "sqlite3://#{ Dir.pwd}/development.db")
end

configure :production do
  DataMapper.setup(:default, ENV['DATABASE_URL'])
end

class Soundtrack
  include DataMapper::Resource
  property :id, Serial
  property :genre, String
  property :tagline, String
  property :created_at, DateTime
  property :title, String
  property :createdby, String
end

class Songs
  include DataMapper::Resource
  property :id, Serial
  property :songtitle, String
  property :artist, String
  property :scene, String
end

DataMapper.finalize

configure :development do
  DataMapper.auto_migrate!
end



#Routes

get '/soundtrack' do
  @soundtrack = Soundtrack.all
  slim :soundtrack
end

get '/singletrack' do
  @songs = Songs.all
  slim :singletrack
end


get '/soundtrack/new' do
  @soundtrack = Soundtrack.new
  slim :new_soundtrack
end

get '/soundtrack/:id' do
  @soundtrack = Soundtrack.get(params[:id])
  slim :show_soundtrack
end

get '/soundtrack/:id/edit' do
  @soundtrack = Soundtrack.get(params[:id])
  slim :edit_soundtrack
end

post '/soundtrack' do
  @soundtrack = Soundtrack.create(params[:soundtrack])
  redirect to("/soundtrack/#{@soundtrack.id}")
end

post '/soundtrack/:id' do
   @soundtrack = Soundtrack.get(params[:id]).songinfo.create params['songinfo']
   redirect back
end

post '/songs/:id' do
   @songs = Songs.create(params[:songs])
   redirect back
end

put '/soundtrack/:id' do
    soundtrack = Soundtrack.get(params[:id])
    soundtrack.update(params[:soundtrack])
    redirect to('/soundtrack/[:id]')
end

delete '/soundtrack/:id' do
    Soundtrack.get(params[:id]).destroy
    redirect to('/soundtrack')
end

delete '/songinfo/:id' do
    Songinfo.get(params[:id]).destroy
    redirect back
end 

HTML (Slim):

.frame
  .row
    <div class="table-responsive">
      <table class="table">
        thead.background-black
          <tr>
            th.text-title Song
            th.text-title Artist
            th.text-title Scene

          </tr>
        </thead>
        <tbody>
           - if @songs.any?
            tr#songs
              [email protected] do |songs|
                tr
                  th #{songs.songtitle}
                  th #{soundtrack.artist}
                  th #{soundtrack.scene}
                </tr>
           - else
             tr
               th  No songs have been created yet!
        </tbody>
      </table>
    </div>


    .col-md-2
.col-md-10
  pre.pre-black

    row
      form-horizontal
        form-group
           col-sm-2
             label for="Song Title"
               p.text-title.form-lower Soundtrack Title
             col-sm-2
               input.form-control type="string" name="songs[songtitle]" value="#{@songs.songtitle}"

    row
      form-horizontal
        form-group
          col-sm-2
            label for="Song Artist"
             p.text-title.form-lower Song Artist
            col-sm-10
            input.form-control type="string" name="songs[artist]" value="#{@songs.artist}"


    row
      form-horizontal
        form-group
          col-sm-2
            label for="Scene"
              p.text-title.form-lower Scene in Moveie
          col-sm-10
            input.form-control type="string" name="songs[scene]" value="#{@songs.scene}"

    .col-md-6
      h3.bump class==current?("/songs") Add A New Song
      .form method="POST" action="/songs"
        input.lower.link-size type="submit" class="text-center" value="Save Song"

Gem File:

source :rubygems
gem "sinatra"
gem "slim"
gem "data_mapper"
gem "dm-timestamps"
gem "thin"
gem "dm-postgres-adapter", :group => :production
gem "dm-sqlite-adapter", :group => :development
gem 'pg', '~> 0.18.4'

Upvotes: 2

Views: 1584

Answers (3)

nishant
nishant

Reputation: 925

Check using

@songs.present?

To learn more about any?, present?, empty?, blank? look at this link.

Upvotes: 1

Maxim Fedotov
Maxim Fedotov

Reputation: 1357

Out of the top of my mind, it might that you don't have any songs. You can't call .any? on a nil, which results in this error. Make sure you have songs and try again.

And to avoid this error in case there is nil, use [email protected]_s.empty? or make sure it returns an [] instead of nil

Upvotes: 1

fabriciofreitag
fabriciofreitag

Reputation: 2883

Maxim is right.

You can either do his way or:

Combine the checking:

if @songs && @songs.any?

Initialize @songs in the controller call, so it is not nil, but an empty array:

@songs = []

Upvotes: 0

Related Questions