I think I have a logic error in program flow, which returns NoMethodError
First, a piece of code which causes error.
<input id="#identity" type="number" name="journal[identity]" value="<%= @journal.identity unless @journal.identity.nil? %>" />
#Error Text
NoMethodError at /profile
undefined method `identity' for nil:NilClass
file: journal_form.erb location: block in singleton class line: 2
The code inside the input tag is the exact code piece which described in error text.
My program flow is like that.
/profile
page1 is ok. Users can log in and out without problem. For 2nd step, code is like that
#profile.erb
<% if session[:user].role == 1 %>
<%= erb :assign_doctor %>
<% elsif session[:user].role == 2 %>
<%= erb :journal_form %>
<% elsif session[:user].role == 3 %>
<pre>
Silence!
</pre>
<% elsif session[:user].role == 4 %>
<%= erb :doctor_screen %>
<% end %>
the 'journal_form.erb' file in second condition.
<input id="#identity" type="number" name="journal[identity]"
value="<%= @journal.identity unless @journal.identity.nil? %>" />
.... # some other attributes like that.
<% if session[:user].role == 1 %>
<% if journal.viewed == false %>
<input id="#assigned_doctor" type = "text" name="journal[assigned_doctor]" />
<% else %>
<input id="#assigned_doctor" type = "text" name="journal[assigned_doctor]" value="<%= @journal.assigned_doctor unless @journal.assigned_doctor.nil? %>" />
<% end %>
I've also created CRUD resources for journal
model entries (in other file). And without yielding CRUD views into profile
they work ok.
Maybe problem is, the profile
is not aware of the context passed into it, so it responses like that. But have no any idea how to fix it.
I can add more code, if you want.
In summation:
When @journal == nil
why does <%=@journal.identity unless @journal.identity.nil?%>
return undefined method 'identity' for nil:NilClass
?
Below there are some helpful resources:
in user.rb (contains 3 classes/models) in the same directory with main.rb.
# model declerations end here
DataMapper.finalize
module JournalHelpers
def find_journals
@journals = Journal.all
end
def find_journal
Journal.get(params[:id])
end
def create_journal
@journal = Journal.create(params[:journal])
end
end
helpers JournalHelpers
get '/journals' do
find_journals
erb :journals
end
#new
get '/journals/new' do
#protected!
@journal = Journal.new
erb :new_journal
end
#show
get '/journals/:id' do
@journal = find_journal
erb :show_journal
end
#create
post '/journals' do
#protected!
flash[:notice]= "Journal was succesfull posted" if create_journal
redirect to("/journals/#{@journal.id}")
end
#edit
get '/journals/:id/edit' do
#protected!
@journal = find_journal
erb :edit_journal
end
#put/update
put '/journals/:id' do
#protected!
journal = find_journal
if journal.update(params[:journal])
flash[:notice] = "Journal successfully updated"
end
redirect to("/journals/#{journal.id}")
end
Program structure
├── assets
│ ├── css
│ │ ├── application.css
│ │ ├── jquery-ui.min.css
│ │ └── main.css
│ ├── images
│ │ ├── loader.gif
│ │ └── nurse_shshsh.jpeg
│ └── js
│ ├── application.js
│ ├── jquery.min.js
│ └── jquery-ui.min.js
├── main.rb
├── user.rb
├── users.db
└── views
├── about.erb
├── assign_doctor.erb
├── contact.erb
├── doctor_screen.erb
├── edit_journal.erb
├── home.erb
├── journal_form.erb
├── journals.erb
├── layout.erb
├── leftcolumn.erb
├── login.erb
├── nav.erb
├── new_journal.erb
├── notifications.erb
├── profile.erb
└── show_journal.erb
Checking for if journal is nil.
get '/profile' do
if !authorized?
redirect to('/login')
else
puts "nihil" if @journal.nil?
erb :profile
end
end
server log
127.0.0.1 - - [29/Jun/2015:22:35:33 +0500] "GET /profile HTTP/1.1" 302 - 0.0029
127.0.0.1 - - [29/Jun/2015:22:35:33 +0500] "GET /login HTTP/1.1" 200 212 0.0024
127.0.0.1 - - [29/Jun/2015:22:35:42 +0500] "POST /login HTTP/1.1" 303 - 0.0167
nihil
127.0.0.1 - - [29/Jun/2015:22:35:43 +0500] "GET /profile HTTP/1.1" 200 1047 0.0106
@journal is nil.
It looks to me that your code are relying on the fact that there is a @journal
field set. (And whose journal is this anyway?) It is certainly not being set in main.rb
. You should get the data you need in the get '/profile'
block. Something along the lines of:
get '/profile' do
if !authorized?
redirect to('/login')
else
@journal = Journal.get(params[:id])
erb :profile
end
end
There are various ways to do this. It is normally good to avoid any shared state between calls and instead getting all needed data in each specific request. (Data can still be reused as in your JournalHelper module.) If database access becomes a bottle neck the best way forward is usually to introduce a cache in front of the database or the web server.