【问题标题】:Modules won't allow instances of class to be made模块不允许创建类的实例
【发布时间】:2012-12-19 00:07:30
【问题描述】:

我需要阅读我被告知的更多 Ruby 理论,这很好,但我阅读的大多数文献都在非常高的水平上进行了解释,我不明白。所以这引出了我的问题和我的代码

我有一个处理我的 api 调用的模块

module Book::BookFinder

BOOK_URL = 'https://itunes.apple.com/lookup?isbn='

def book_search(search)
response = HTTParty.get(BOOK_URL + "#{search}", :headers => { 'Content-Type' => 'application/json', 'Accept' => 'application/json' })
results = JSON.parse(response.body)["results"]
end
end

然后是我的控制器

class BookController < ApplicationController
before_filter :authenticate_admin_user!
include Book::BookFinder

def results
results = book_search(params[:search])
@results = results
@book = Book.new
@book.author = results[0]["artistName"]

end

def create
@book = Book.new(params[:book])
 if @book.save
redirect_to @book, notice: 'Book was successfully saved'
 else
render action:new
end
end
end

我想要做的是将作者值保存到我的 Book 模型中。我收到错误消息

undefined method `new' for Book:Module

进行搜索时,在以前的帖子中已向我解释过。无法实例化模块。解决方案是上课?但也许我没有正确理解,因为我不知道该把这门课放在哪里。给我的解决方案是

 class Book
  def initialize
   # put constructor logic here
  end

 def some_method
 # methods that can be called on the instance
 # eg:
 # @book = Book.new
 # @book.some_method
 end

# defines a get/set property
  attr_accessor :author
# allows assignment of the author property
end

现在我确信这是一个有效的答案,但谁能解释发生了什么?看到一个有解释的例子对我来说比阅读书中的一行又一行的文字更有益。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 class module


    【解决方案1】:
    module Finders
    
      ## Wrap BookFinder inside another module, Finders, to better organise related
      ## code and to help avoid name collisions
      ## lib/finders/book_finder.rb
      module BookFinder
        def bar
          puts "foo"
        end
      end  
    end
    
    
    ## Another BookFinder module, but this one is not wrapped.
    ## lib/book_finder.rb
    module BookFinder
      def foo
        puts 'bar'
      end
    end
    
    
    ## Book is a standard Rails model inheriting from ActiveRecord
    ## app/models/book.rb
    class Book < ActiveRecord::Base
      ## Mixin methods from both modules
      include BookFinder
      include HelperLibs::BookFinder
    end
    
    ## app/controllers/books_controller.rb
    class BookController
      def create
        book = Book.new
        book.foo
        book.bar
    
      end
    end
    
    
    BookController.new.create
     - bar
     - foo
    

    在您的代码中,您正在创建一个具有相同名称的模块和一个类 - 这是不允许的。该模块将覆盖该类,因为它是第二个加载的。

    【讨论】:

    • 感谢您的回答,所以通过将 bookfinder 模块包装在另一个模块中,是否可以创建 book 类的实例?
    • 没有。您可以创建 Book 的实例,因为它是一个类,并且不会被同名模块覆盖。
    • 恐怕我还是不明白,我想回到绘图板上,谢谢你的尝试。我已经接受了你的回答,但我确定你是对的
    • 我用另一个模块包装了 BookFinder,以演示如何将相似的类/模块组合在一起。例如,在编写 ruby​​ Gem 时,您应该使用与 gem 同名的模块来包装代码,这样您的模块/类就不会与应用程序使用的其他库发生冲突。
    • 你的代码唯一真正的问题是你有一个模块和一个类共享相同的名称,Book
    猜你喜欢
    • 2020-03-09
    • 2016-07-26
    • 2017-03-03
    • 2018-02-24
    • 1970-01-01
    • 2017-10-12
    • 1970-01-01
    • 2011-04-29
    • 1970-01-01
    相关资源
    最近更新 更多