ruby on Rails 中的方法查询 - 未定义的方法“read”为了

发布于 2024-09-26 02:36:19 字数 1394 浏览 0 评论 0原文

作为学习 ruby​​/rails 的一部分,我正在尝试实现 http://github.com/professionalnerd /simple-private-messages 从头开始​​进入我的应用程序,而不是仅仅安装插件。 (我知道,这给自己带来了麻烦,但这是一次很好的学习经历。)

我创建了模型,关联看起来不错,我可以很好地创建新消息,它们会显示在收件人邮箱中。但是,如果我单击查看一条消息(调用消息控制器中的显示方法),它就会在寻找名为“read”的方法时出错,例如。

undefined method `read' for #<Class:0xb6f9ef78>

我应该把“read”方法放在哪里。在 private_messages_extensions.rb (插件源)中,它具有:

  module ClassMethods
    # Ensures the passed user is either the sender or the recipient then returns the message.
    # If the reader is the recipient and the message has yet not been read, it marks the read_at timestamp.
    def read(id, reader)
      message = find(id, :conditions => ["sender_id = ? OR recipient_id = ?", reader, reader])
      if message.read_at.nil? && reader == message.recipient
        message.read_at = Time.now
        message.save!
      end
      message
    end
  end

  module InstanceMethods
    # Returns true or false value based on whether the a message has been read by it's recipient.
    def read?
      self.read_at.nil? ? false : true
    end

类方法和实例方法之间的关系与直接插入到我自己的消息控制器中有何关系?模型?我以为我插入

def read(id, reader)
...
end

了模型,但是读取了?插件代码的实例方法部分中的方法让我感到困惑,我在查看消息时继续收到错误。

帮助表示赞赏!

As part of learning ruby/rails, I'm trying to implement http://github.com/professionalnerd/simple-private-messages into my application from scratch, instead of just installing the plugin. (I know, causing myself trouble but it's a good learning experience.)

I created the model, and the associations seem ok and I can create new messages fine and they show up in the recipients mailbox. But if I click to view one message (calls the show method in the message controller) it trips up on looking for a method called 'read' eg.

undefined method `read' for #<Class:0xb6f9ef78>

Where should I put the 'read' method. In private_messages_extensions.rb (the plugin source) it has:

  module ClassMethods
    # Ensures the passed user is either the sender or the recipient then returns the message.
    # If the reader is the recipient and the message has yet not been read, it marks the read_at timestamp.
    def read(id, reader)
      message = find(id, :conditions => ["sender_id = ? OR recipient_id = ?", reader, reader])
      if message.read_at.nil? && reader == message.recipient
        message.read_at = Time.now
        message.save!
      end
      message
    end
  end

  module InstanceMethods
    # Returns true or false value based on whether the a message has been read by it's recipient.
    def read?
      self.read_at.nil? ? false : true
    end

What is the relationship between Class methods and Instance methods in relation to inserting directly into my own messages controller & model? I thought I inserted

def read(id, reader)
...
end

into the model, but the read? method in the instance methods section of the plugin code is confusing me and I continue to get the error on viewing a message.

Help appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

救赎№ 2024-10-03 02:36:19

ClassMethods / InstanceMethods 是基于以下代码的标准 Ruby 技术:

def self.included(base)
  base.extend ClassMethods
  base.include InstanceMethods
end 

您将(大致)在原始代码中找到该代码。顺便说一句,ActiveSupport::Concern 可以简化上面的代码(请查看文档以获取更多信息)

因此,每当模块包含在类中时,ClassMethods 模块中的所有方法都将变成 class目标类的方法和InstanceMethods中的所有方法都将成为目标类的实例方法。

所以你的 read 方法是类方法,必须调用为:

m = MyModel.new
m.read?          # => ok, it is an instance method
MyModel.read     # => ok, it is a class method
m.read           # => oops, WRONG! FAILURE! 
                 # You are calling class method through object

元编程规则!

如果你重写没有元数据的代码,你应该将其写为:

class MyModel
  def self.read
  end

  def read?
  end

end    

ClassMethods / InstanceMethods is standard Ruby technique that is based on this code:

def self.included(base)
  base.extend ClassMethods
  base.include InstanceMethods
end 

which you will (roughly) find in the original code. By the way there is ActiveSupport::Concern that can simplify the code above (take a look into the documentation for more info)

So whenever the module is included in class then all methods in ClassMethods module will became class methods of the target class and all methods in InstanceMethods will become instance methods of target class.

So your read method is class method, which has to be called as:

m = MyModel.new
m.read?          # => ok, it is an instance method
MyModel.read     # => ok, it is a class method
m.read           # => oops, WRONG! FAILURE! 
                 # You are calling class method through object

Meta-programming rules!

If you rewrite the code without meta thing, you should write it as:

class MyModel
  def self.read
  end

  def read?
  end

end    
暗喜 2024-10-03 02:36:19

我没有看过该插件,但根据其他插件的标准,我认为您需要这样的东西:

def self.read(id, reader)
  ...
end

这将使其成为一个类方法,可以通过调用 User.read 进行访问。

(我假设这是因为 module ClassMethods 块)

I haven't looked at the plug-in but based on the standards from other plug-ins, I think you need something like this:

def self.read(id, reader)
  ...
end

This will make it a class method, accessible by calling User.read.

(I am assuming this because of the module ClassMethods block)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文