SitePoint Sponsor

User Tag List

Results 1 to 10 of 10
  1. #1
    SitePoint Member
    Join Date
    Oct 2003
    Location
    earth
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Question Ruby/Rails Basic Help!

    ok I am trying to go throught the ruby/rails tutorial on the appl site (http://developer.apple.com/tools/rubyonrails.html), but when I get to the "business logic" it won't work. For my expenses_helper.rb I have

    Code:
    module ExpensesHelper
      def total(account)
        style = account.total_expenses > account.budget ? 'color: red' : 'color: black'
        %(<span style="#{style}">#{number_to_currency(account.total_expenses)}</span>)
      end
    end
    for my app/models/account.rb file I have,

    Code:
    def total_expenses
      expenses.inject(0) {|total, expense| total + expense.amount }
    end
    and for my show.rhtml I have

    Code:
    <% for column in Account.content_columns %>
    <p>
      <b><%= column.human_name %>:</b> <%=h @account.send(column.name) %>
    </p>
    <% end %>
    
    <%= link_to 'Edit', :action => 'edit', :id => @account %> |
    <%= link_to 'Back', :action => 'list' %>
    
    
    <% if @account.has_expenses? %>
      <h3>Itemized Expenses</h3>
      <table>
      <% for expense in @account.expenses %>
        <tr>
          <td><%= expense.paid_on %></td>
          <td><%= expense.payable_to %></td>
          <td align="right"><%= number_to_currency(expense.amount) %></td>
        </tr>
    
      <% end %>
    	<tr>
    	  <td align="right" colspan="3">
    	    <strong>Total</strong>: <%= total(@account) %>
    	  </td>
    	</tr>
      </table>
    
    <% end %>
    
    
    
    <%= start_form_tag :action => 'record', :id => @account %>
      <p>
        On <%= date_select 'expense', 'paid_on', :order => [:month, :day, :year] %>
        to <%= text_field 'expense', 'payable_to', :size => 25 %>
        in the amount of $<%= text_field 'expense', 'amount', :size => 9 %>
      </p>
      <%= submit_tag 'Record!' %>
    <%= end_form_tag %>
    This is, I believe, exactly how the tutorial says to do it, yet I keep getting

    HTML Code:
     NoMethodError in Expenses#show
    
    Showing app/views/expenses/show.rhtml where line #24 raised:
    
    private method `total_expenses' called for #<Account:0x229a8e4>
    
    Extracted source (around line #24):
    
    21:   <% end %>
    22: 	<tr>
    23: 	  <td align="right" colspan="3">
    24: 	    <strong>Total</strong>: <%= total(@account) %>
    25: 	  </td>
    26: 	</tr>
    27:   </table>
    
    RAILS_ROOT: script/../config/..
    Application Trace | Framework Trace | Full Trace
    
    /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.2/lib/active_record/base.rb:1792:in `method_missing'
    #{RAILS_ROOT}/app/helpers/expenses_helper.rb:3:in `total'
    #{RAILS_ROOT}/app/views/expenses/show.rhtml:24:in `_run_rhtml_expenses_show'
    
    /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.2/lib/active_record/base.rb:1792:in `method_missing'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_view/base.rb:314:in `compile_and_render_template'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_view/base.rb:290:in `render_template'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_view/base.rb:249:in `render_file'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/base.rb:699:in `render_file'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/base.rb:621:in `render_with_no_layout'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/layout.rb:243:in `render_without_benchmark'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/benchmarking.rb:53:in `render'
    /usr/local/lib/ruby/1.8/benchmark.rb:293:in `measure'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/benchmarking.rb:53:in `render'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/base.rb:911:in `perform_action_without_filters'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/filters.rb:368:in `perform_action_without_benchmark'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/benchmarking.rb:69:in `perform_action_without_rescue'
    /usr/local/lib/ruby/1.8/benchmark.rb:293:in `measure'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/benchmarking.rb:69:in `perform_action_without_rescue'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/rescue.rb:82:in `perform_action'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/base.rb:381:in `process_without_filters'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/filters.rb:377:in `process_without_session_management_support'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/session_management.rb:117:in `process'
    /usr/local/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/dispatcher.rb:38:in `dispatch'
    /usr/local/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/webrick_server.rb:115:in `handle_dispatch'
    /usr/local/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/webrick_server.rb:81:in `service'
    /usr/local/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
    /usr/local/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
    /usr/local/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
    /usr/local/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
    /usr/local/lib/ruby/1.8/webrick/server.rb:95:in `start'
    /usr/local/lib/ruby/1.8/webrick/server.rb:92:in `start'
    /usr/local/lib/ruby/1.8/webrick/server.rb:23:in `start'
    /usr/local/lib/ruby/1.8/webrick/server.rb:82:in `start'
    /usr/local/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/webrick_server.rb:67:in `dispatch'
    /usr/local/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/commands/servers/webrick.rb:59
    /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:21:in `require'
    /usr/local/lib/ruby/gems/1.8/gems/activesupport-1.3.1/lib/active_support/dependencies.rb:147:in `require'
    /usr/local/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/commands/server.rb:30
    /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:21:in `require'
    /usr/local/lib/ruby/gems/1.8/gems/activesupport-1.3.1/lib/active_support/dependencies.rb:147:in `require'
    script/server:3
    
    /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.2/lib/active_record/base.rb:1792:in `method_missing'
    #{RAILS_ROOT}/app/helpers/expenses_helper.rb:3:in `total'
    #{RAILS_ROOT}/app/views/expenses/show.rhtml:24:in `_run_rhtml_expenses_show'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_view/base.rb:314:in `compile_and_render_template'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_view/base.rb:290:in `render_template'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_view/base.rb:249:in `render_file'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/base.rb:699:in `render_file'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/base.rb:621:in `render_with_no_layout'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/layout.rb:243:in `render_without_benchmark'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/benchmarking.rb:53:in `render'
    /usr/local/lib/ruby/1.8/benchmark.rb:293:in `measure'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/benchmarking.rb:53:in `render'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/base.rb:911:in `perform_action_without_filters'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/filters.rb:368:in `perform_action_without_benchmark'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/benchmarking.rb:69:in `perform_action_without_rescue'
    /usr/local/lib/ruby/1.8/benchmark.rb:293:in `measure'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/benchmarking.rb:69:in `perform_action_without_rescue'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/rescue.rb:82:in `perform_action'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/base.rb:381:in `process_without_filters'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/filters.rb:377:in `process_without_session_management_support'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/session_management.rb:117:in `process'
    /usr/local/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/dispatcher.rb:38:in `dispatch'
    /usr/local/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/webrick_server.rb:115:in `handle_dispatch'
    /usr/local/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/webrick_server.rb:81:in `service'
    /usr/local/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
    /usr/local/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
    /usr/local/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
    /usr/local/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
    /usr/local/lib/ruby/1.8/webrick/server.rb:95:in `start'
    /usr/local/lib/ruby/1.8/webrick/server.rb:92:in `start'
    /usr/local/lib/ruby/1.8/webrick/server.rb:23:in `start'
    /usr/local/lib/ruby/1.8/webrick/server.rb:82:in `start'
    /usr/local/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/webrick_server.rb:67:in `dispatch'
    /usr/local/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/commands/servers/webrick.rb:59
    /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:21:in `require'
    /usr/local/lib/ruby/gems/1.8/gems/activesupport-1.3.1/lib/active_support/dependencies.rb:147:in `require'
    /usr/local/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/commands/server.rb:30
    /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:21:in `require'
    /usr/local/lib/ruby/gems/1.8/gems/activesupport-1.3.1/lib/active_support/dependencies.rb:147:in `require'
    script/server:3
    
    Request
    
    Parameters: {"id"=>"1"}
    
    Show session dump
    
    --- 
    flash: !map:ActionController::Flash::FlashHash {}
    
    
    Response
    Headers: {"cookie"=>[], "Cache-Control"=>"no-cache"}

    Any ideas? I think it might have to do with not finding the method or the method total() being private. I hope I don't have anything wrong with my ruby/rails install. Thanks a million!
    Last edited by acrylik; Apr 25, 2006 at 21:35.

  2. #2
    SitePoint Evangelist
    Join Date
    Jun 2004
    Location
    California
    Posts
    440
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Paste your entire model here... for some reason the method total_expenses is private.
    Happy switcher to OS X running on a MacBook Pro.

    Zend Certified Engineer

  3. #3
    SitePoint Member
    Join Date
    Oct 2003
    Location
    earth
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ok, here is app/models/account.rb

    Code:
    class Account < ActiveRecord::Base
    
      validates_presence_of :name
      validates_numericality_of :budget
      
      has_many :expenses, :order => "paid_on"
    end
    
    def total_expenses
      expenses.inject(0) {|total, expense| total + expense.amount }
    end
    and here is app/models/expense.rb

    Code:
    class Expense < ActiveRecord::Base
      belongs_to :account
    end
    Also, here is the file with everything so maybe you can run it and see if it works.
    Attached Files Attached Files

  4. #4
    Mal Reynolds Mandibal's Avatar
    Join Date
    Aug 2003
    Location
    Columbus
    Posts
    718
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Move the total_expenses method inside the "end" just above it's declaration. Right now it's not inside the class definition.

    PHP Code:
    class Account ActiveRecord::Base

      validates_presence_of 
    :name
      validates_numericality_of 
    :budget
      
      has_many 
    :expenses, :order => "paid_on"

      
    def total_expenses
        expenses
    .inject(0) {|totalexpensetotal expense.amount }
      
    end

    end 
    <-- was above the total_expenses method 
    Erh

  5. #5
    SitePoint Evangelist
    Join Date
    Jun 2004
    Location
    California
    Posts
    440
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    So the method wasn't even in the model... its strange that the error said that the method was a private method even though it didn't exist. I would've expected the NoMethodError saying "Nothing responded to Account#total_expenses."
    Happy switcher to OS X running on a MacBook Pro.

    Zend Certified Engineer

  6. #6
    Mal Reynolds Mandibal's Avatar
    Join Date
    Aug 2003
    Location
    Columbus
    Posts
    718
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by xmitchx
    So the method wasn't even in the model... its strange that the error said that the method was a private method even though it didn't exist. I would've expected the NoMethodError saying "Nothing responded to Account#total_expenses."
    Me too. So I suppose we'll see if that was just a typo in that post. I didn't look at the zip yet so I don't know if the posted code is accurate. That was the first thing that popped out though.
    Erh

  7. #7
    SitePoint Member
    Join Date
    Oct 2003
    Location
    earth
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks so much! I fixed it and it is working great!

  8. #8
    SitePoint Evangelist
    Join Date
    Jun 2004
    Location
    California
    Posts
    440
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Mandibal
    Me too. So I suppose we'll see if that was just a typo in that post. I didn't look at the zip yet so I don't know if the posted code is accurate. That was the first thing that popped out though.
    I just tested some code and indeed it gives the error acrylik posted! This has to be some sort of trivial bug in Ruby...

    Code tested:
    Code:
     class Fake
       def run_me(args)
     	puts args
       end
     end
     
     def play_me(args)
       puts 'Oh!'
     end
     
     fake = Fake.new
     fake.run_me('hi')
     fake.play_me
    And error outputted:
    hi

    NoMethodError: private method `play_me' called for #<Fake:0x32ca9c>
    Happy switcher to OS X running on a MacBook Pro.

    Zend Certified Engineer

  9. #9
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I don't think it is a bug.

    Remember that "global" methods like play_me in your example are defined in the Kernel module. Object includes Kernel, so all Kernel methods are available for every object. To prevent this, they have been made private, so only callable in the defining scope.

  10. #10
    SitePoint Evangelist
    Join Date
    Jun 2004
    Location
    California
    Posts
    440
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Fenrir2
    I don't think it is a bug.

    Remember that "global" methods like play_me in your example are defined in the Kernel module. Object includes Kernel, so all Kernel methods are available for every object. To prevent this, they have been made private, so only callable in the defining scope.
    Ah, yes I never thought of it that way. Thank you for clearing that up
    Happy switcher to OS X running on a MacBook Pro.

    Zend Certified Engineer


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •