Sinatra:NoMethodError

时间:2015-06-29 07:41:19

标签: ruby sinatra nomethoderror ruby-datamapper

Whole source code here

我认为程序流中存在逻辑错误,返回NoMethodError

首先,一段导致错误的代码。

<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 

输入标记内的代码是错误文本中描述的确切代码段。

我的程序流程就是这样。

  1. 用户登录
  2. 如果身份验证成功,他/她将被重定向到/profile页面
  3. 根据他们的角色/特权,他们会在'/ profile'的主区域内看到不同的内容。内容是数据库
  4. 1没问题。用户可以毫无问题地登录和注销。对于第二步,代码就是那样

    #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 %>
    

    第二个条件下的'journal_form.erb'文件。

    <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 %>
    

    我还为journal模型条目(在其他文件中)创建了CRUD资源。并且没有将CRUD视图放到profile中,它们可以正常工作。

    也许问题是,profile不知道传递给它的上下文,所以它会像那样响应。但不知道如何解决它。

    如果你愿意,我可以添加更多代码。

    总结:

    @journal == nil为什么<%=@journal.identity unless @journal.identity.nil?%>会返回undefined method 'identity' for nil:NilClass

    下面是一些有用的资源:

    使用main.rb在同一目录中的 user.rb (包含3个类/模型)中的

    # 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
    

    计划结构

    ├── 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
    

    检查日记是否为零。

    get '/profile' do 
        if !authorized?
            redirect to('/login')
        else
            puts "nihil" if @journal.nil?
            erb :profile
        end
    end
    

    服务器日志

    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是零。

3 个答案:

答案 0 :(得分:1)

如果@journal为nil,@ journal.identity或@ journal.almost_any_function将引发错误。我想你在这之后的实际情况是:

<%=@journal.identity unless @journal.nil?%>

如评论中所述。或者#try在rails中定义,你可以这样做:

<%= @journal.try(:identity) %>

在@journal本身为零的情况下,两者都会返回nil而不会引发NoMethod错误。如果定义了@journal,它将返回@ journal.identity

的值

答案 1 :(得分:1)

正如我在评论中所说,最明显的解决方案是使用<%= @journal.identity unless @journal.nil?%>,因为如果@journal == nil那么@journal.nil?将返回true,整个语句将返回nil。发布完整代码后,我会继续更新此答案。

答案 2 :(得分:1)

在我看来,您的代码依赖于@journal字段集的事实。 (无论如何,它的期刊是什么?)肯定没有在main.rb中设定。您应该在get '/profile'块中获取所需的数据。有点像:

get '/profile' do
  if !authorized?
    redirect to('/login')
  else
    @journal = Journal.get(params[:id])
    erb :profile
  end
end

有多种方法可以做到这一点。通常最好避免调用之间的任何共享状态,而是在每个特定请求中获取所有需要的数据。 (数据仍然可以像在JournalHelper模块中那样重复使用。)如果数据库访问成为瓶颈,最好的方法通常是在数据库或Web服务器前引入缓存。