2010-10-03 2 views
2

Как часть обучения ruby ​​/ rails, я пытаюсь реализовать http://github.com/professionalnerd/simple-private-messages в своем приложении с нуля, вместо того, чтобы просто устанавливать плагин. (Я знаю, что вызвало у меня проблемы, но это хороший опыт обучения.)Методы запроса в ruby ​​on rails - неопределенный метод `read 'для

Я создал модель, и ассоциации выглядят нормально, и я могу создавать новые сообщения в порядке, и они отображаются в почтовом ящике получателей. Но если я нажму для просмотра одного сообщения (вызывает метод show в контроллере сообщений), он отправляется на поиски метода, называемого «читать», например.

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

Где я должен поместить метод «читать». В 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 

в модель, но прочитал? метод в разделе методов методов кода плагина меня сбивает с толку, и я продолжаю получать ошибку при просмотре сообщения.

Помогите оценить!

ответ

0

методы класса/InstanceMethods является стандартным методом рубин, который основан на этом коде:

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

который вы (примерно) найти в оригинале код. Кстати есть ActiveSupport :: опасение, что может упростить код, указанным выше (посмотрите в документацию для получения дополнительной информации)

Таким образом, когда модуль включен в классе, то все методы в модуле будут методы класса стали класса методов целевого класса и всех методов в 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  
+0

Спасибо за очень тщательный ответ! – Dave

0

Я не смотрел на плагин, но на основе стандартов от других плагинов, я думаю, что нужно что-то вроде этого:

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

Это позволит сделать его метод класса, доступный по вызывающий User.read.

(я предполагаю, что это из-за module ClassMethods блока)

Смежные вопросы