Reputation: 25
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
Reputation: 925
Check using
@songs.present?
To learn more about any?, present?, empty?, blank?
look at this link.
Upvotes: 1
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
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