为什么我的名字方法未定义?

时间:2015-07-10 15:48:03

标签: ruby-on-rails

我收到了一个未定义的方法`name',用于我的Rails项目的#error。我知道通过使用我的控制台进行双重检查为事件定义了名称,所以我不明白它为什么不加载。以下是我的一些代码:

应用显示:

<h1><%= @app.title %></h1>
<h5>App URL: <%= @app.url %></h5>
<h5>App User_id: <%= @app.user_id %></h5>
<br>

    <h2> Events </h2>
      <% @events.each do |event| %>
        <div>
          <%= event.name %><span class="badge"><%= event.count %></span>
        </div>
      <% end %>
    <br>
    <%= link_to "Edit", edit_app_path(@app), class: 'btn btn-success' %>

应用控制器:

class AppsController < ApplicationController
  def create
    @app = App.new(params.require(:app).permit(:title, :url))
    @app.user_id = 1
    if @app.save
      flash[:notice] = "App was saved!"
      redirect_to @app
    else
      flash[:error] = "There an error, oh noes!Please try again!"
      render :new
    end
  end

  def new
    @app = App.new
  end

  def show
    @app = App.find(params[:id])
    @events = @app.events.group_by(&:name)
  end

  def index
    @apps = App.all
  end

  def edit
    @app = App.find(params[:id])
  end

  def update
    @app = App.find(params[:id])
     if @app.update_attributes(params.require(:app).permit(:title, :url))
       flash[:notice] = "Application was updated."
       redirect_to @app
     else
       flash[:error] = "There was an error saving the app. Please try again."
       render :edit
     end
  end

  def destroy
    @app = App.find(params[:id])
    if @app.destroy
      flash[:notice] = "App was removed."
      redirect_to @app
    else
      flash[:error] = "App couldn't be deleted. Try again."
      redirect_to @app
    end

     respond_to do |format|
       format.html
       format.js
     end
  end
end

活动种子:

create_table "events", force: :cascade do |t|
    t.integer  "app_id"
    t.string   "name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

应用型号:

class App < ActiveRecord::Base
  belongs_to :user
  has_many :events
end

完成错误日志:

Completed 500 Internal Server Error in 19ms

ActionView::Template::Error (undefined method `name' for #<Array:0x007fcc53394af0>):
     6: <h2> Events </h2>
     7:   <% @events.each do |event| %>
     8:     <div>
     9:       <%= event.name %><span class="badge"><%= event.count %></span>
    10:     </div>
    11:   <% end %>
    12: <br>
  app/views/apps/show.html.erb:9:in `block in _app_views_apps_show_html_erb__2949113196422864311_70257764571040'
  app/views/apps/show.html.erb:7:in `each'
  app/views/apps/show.html.erb:7:in `_app_views_apps_show_html_erb__2949113196422864311_70257764571040'


  Rendered /Users/ericpark/.rvm/gems/ruby-2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/_source.erb (7.1ms)
  Rendered /Users/ericpark/.rvm/gems/ruby-2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (4.1ms)
  Rendered /Users/ericpark/.rvm/gems/ruby-2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (0.9ms)
  Rendered /Users/ericpark/.rvm/gems/ruby-2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb within rescues/layout (71.2ms)
  Rendered /Users/ericpark/.rvm/gems/ruby-2.2.0/gems/web-console-2.1.3/lib/web_console/templates/_markup.html.erb (0.7ms)
  Rendered /Users/ericpark/.rvm/gems/ruby-2.2.0/gems/web-console-2.1.3/lib/web_console/templates/style.css.erb within layouts/inlined_string (0.7ms)
  Rendered /Users/ericpark/.rvm/gems/ruby-2.2.0/gems/web-console-2.1.3/lib/web_console/templates/_inner_console_markup.html.erb within layouts/inlined_string (0.5ms)
  Rendered /Users/ericpark/.rvm/gems/ruby-2.2.0/gems/web-console-2.1.3/lib/web_console/templates/_prompt_box_markup.html.erb within layouts/inlined_string (0.3ms)
  Rendered /Users/ericpark/.rvm/gems/ruby-2.2.0/gems/web-console-2.1.3/lib/web_console/templates/console.js.erb within layouts/javascript (69.6ms)
  Rendered /Users/ericpark/.rvm/gems/ruby-2.2.0/gems/web-console-2.1.3/lib/web_console/templates/main.js.erb within layouts/javascript (0.4ms)
  Rendered /Users/ericpark/.rvm/gems/ruby-2.2.0/gems/web-console-2.1.3/lib/web_console/templates/error_page.js.erb within layouts/javascript (0.7ms)
  Rendered /Users/ericpark/.rvm/gems/ruby-2.2.0/gems/web-console-2.1.3/lib/web_console/templates/index.html.erb (156.5ms)

2 个答案:

答案 0 :(得分:1)

在这种情况下,简单的调试打印将揭示问题。如果您认为应该name @events,则@events未定义?您确定p @events是您认为的吗?

@events = @app.events.group_by(&:name) 行添加到控制器,重试请求并阅读日志。对未来的建议。 :)

问题从这里开始:

group_by

我很确定group_by的输出是散列,其中键是不同的名称,值是所有具有相同名称的事件数组。 (当然,取决于<% @events.each do |event| %> 的具体实施方式)

event

Event这里不是[name, [event1, event2, ...]]类的实例,而是一个双元素数组<% @events.each do |name, events| %> <%= name %> <%= events.length %> 。你应该迭代这个嵌套的数组来获得真正的事件,它们有你想要的方法。

#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/filesystem/path.hpp>
#include <boost/utility/string_ref.hpp>
#include <boost/iostreams/device/mapped_file.hpp>
namespace io = boost::iostreams;
namespace fs = boost::filesystem;


class FastaReader {

public:
    typedef std::pair<boost::string_ref, boost::string_ref> Entry;
    typedef std::vector<Entry> Data;

private:
    Data fV;
    fs::path file;  

public:
    FastaReader(const fs::path & f);
    ~FastaReader();

    const fs::path & getFile() const;
    const Data::const_iterator begin() const;
    const Data::const_iterator end() const;   

private:
    io::mapped_file_source mmap;
    void parse();

};

#include <iomanip>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
//#include "fastaReader.hpp"

#include <boost/iostreams/device/mapped_file.hpp>

using namespace std;

namespace fs = boost::filesystem;
namespace qi = boost::spirit::qi;
namespace pt = boost::posix_time;
namespace io = boost::iostreams;

namespace boost { namespace spirit { namespace traits {
    template <typename It>
    struct assign_to_attribute_from_iterators<boost::string_ref, It, void> {
        static void call(It f, It l, boost::string_ref& attr) { attr = boost::string_ref { f, size_t(std::distance(f,l)) }; }
    };
} } }

template <typename Iterator>
struct FastaGrammar : qi::grammar<Iterator, FastaReader::Data()> {

    FastaGrammar() : FastaGrammar::base_type(fasta) {
        using namespace qi;
        using boost::phoenix::construct;
        using boost::phoenix::begin;
        using boost::phoenix::size;

        entry = ('>' >> raw[ *~char_('\n') ] >> '\n' >> raw[ *~char_('>') ]);
        fasta = *entry >> *eol >> eoi ;

        BOOST_SPIRIT_DEBUG_NODES((fasta)(entry));
    }
  private:
    qi::rule<Iterator, FastaReader::Data()>  fasta;
    qi::rule<Iterator, FastaReader::Entry()> entry;
};

FastaReader::FastaReader(const fs::path & f) : file(f), mmap(file.c_str()) {
    parse();
}

FastaReader::~FastaReader() {}

const fs::path & FastaReader::getFile() const {
    return this->file;
}


const FastaReader::Data::const_iterator FastaReader::begin() const {
    return this->fV.cbegin();
}


const FastaReader::Data::const_iterator FastaReader::end() const {
    return this->fV.cend();
}

void FastaReader::parse() {
    if (this->file.empty())                throw std::runtime_error("FastaReader: No file specified.");
    if (! fs::is_regular_file(this->file)) throw std::runtime_error(string("FastaReader: File not found: ") + this->file.string());

    typedef char const*                  iterator_type;
    typedef FastaGrammar<iterator_type>  fastaGr;

    static const fastaGr fG{};
    try {
        std::cerr << "Measuring: Parsing." << std::endl;
        const pt::ptime startMeasurement = pt::microsec_clock::universal_time();

        iterator_type first(mmap.data()), last(mmap.end());
        qi::phrase_parse(first, last, fG, boost::spirit::ascii::space, this->fV);

        const pt::ptime endMeasurement = pt::microsec_clock::universal_time();
        pt::time_duration duration (endMeasurement - startMeasurement);
        std::cerr << duration <<  std::endl;
    } catch (std::exception const& e) {
        cerr << "error message: " << e.what() << endl;
    }   
}

int main() {
    FastaReader reader("input.txt");

    for (auto& e : reader) std::cout << '>' << e.first << '\n' << e.second << "\n\n";
}

答案 1 :(得分:1)

@events是哈希,你必须像

一样迭代
   <% @events.each do |event| %>
    <div>
      <%= event[0] %><span class="badge"><%= event[1].count %></span>
    </div>
  <% end %>