【问题标题】:NoMethodError undefined method `messages'NoMethodError 未定义方法“消息”
【发布时间】:2014-02-06 11:08:43
【问题描述】:

我正在运行 sidekiq,并且在我的工作日志中收到 NoMethodError 未定义方法“消息”。我已经定义了所有内容,所以我不确定我做错了什么。

 class UserMessageWorker
  include Sidekiq::Worker

  def perform(message_id, recipient_id)
    message = Message.find(message_id)
    user = User.find(recipient_id)
    message.read_at = Time.now
    old_msg_count = user.messages.count
    usermessages = user.received_messages.where("read_at IS NOT NULL").count + user.sent_messages.where("read_at IS NOT NULL").count

    if message.save
      msg_response_time = message.read_at - message.created_at
      readmessages = []
      usermessages.each do |um|
          if um.read_at != nil
               readmessages << um
          end
      end
      response_rate = usermessages/(old_msg_count + 1)
      response_time = ((user.average_response_time * old_msg_count)+msg_response_time)/(old_msg_count + 1)
      user.update_attributes(:response_rate => response_rate, :average_response_time => average_response_time )
    end
  end
end

消息控制器:

def show
  @reply_message = Message.new
    @message = Message.find(params[:id])
    if @message.recipient == current_user
       UserMessageWorker.perform_async(@message.id, current_user.id)
     end
    @message.readingmessage if @message.recipient == current_user
  end

消息模型:

attr_accessible :subject, :conversation_id, :body, :parent_id, :sender_id, :recipient_id, :read_at,:sender_deleted,:recipient_deleted
    validates_presence_of :subject, :message => "Please enter message title"
    has_many :notifications, as: :event
    belongs_to :conversation, inverse_of: :messages
    belongs_to :user
  scope :unread, -> {where('read_at IS NULL')}
  scope :not_deleted_by_recipient, where('messages.recipient_deleted IS NULL OR messages.recipient_deleted = ?', false)
  scope :not_deleted_by_sender, where('messages.sender_deleted IS NULL OR messages.sender_deleted = ?', false)

    belongs_to :sender,
    :class_name => 'User',
    :foreign_key => 'sender_id'
    belongs_to :recipient,
    :class_name => 'User',
    :foreign_key => 'recipient_id'

    def reply
      new_message.reply_from_user_id = self.id #save the user id of original repost, to keep track of where it originally came from
  end

  def self.by_date
      order("created_at DESC")
    end

    # marks a message as deleted by either the sender or the recipient, which ever the user that was passed is.
    # When both sender and recipient marks it deleted, it is destroyed.
    def mark_message_deleted(id,user_id)
            self.sender_deleted = true if self.sender_id == user_id
            self.recipient_deleted = user_id if self.recipient_id == user_id
            (self.sender_deleted > 0 && self.recipient_deleted > 0) ? self.destroy : self.save!
            (self.sender_deleted != 0 && self.recipient_deleted != 0)
        end
    # Read message and if it is read by recipient then mark it is read
    def readingmessage
      self.read_at ||= Time.now
      save
    end

    # Based on if a message has been read by it's recipient returns true or false.
    def read?
        self.read_at.nil? ? false : true
    end

    def self.received_by(user)
       where(:recipient_id => user.id)
     end

     def self.not_recipient_deleted
       where("recipient_deleted = ?", false)
     end

     def self.sent_by(user)
        Message.where(:sender_id => user.id)
      end

      def next(same_recipient = true)
        collection = Message.where('id <> ? AND created_at > ?', self.id, self.created_at).order('created_at ASC')
        collection.where(recipient_id: self.recipient_id) if same_recipient
        collection.first
      end

      def previous(same_recipient = true)
        collection = Message.where('id <> ? AND created_at < ?', self.id, self.created_at).order('created_at DESC')
        collection.where(recipient_id: self.recipient_id) if same_recipient
        collection.first
      end
    end

    private
    def send_notification(message)
      message.notifications.create(user: message.recipient)
    end

用户模型:

 has_secure_password
  attr_accessible :role, :name, :time_zone, :code, :lat, :lon, :city, :age, :age_end, :password_confirmation, :about_me, :feet, :inches, :password, :birthday, :career, :children, :education, :email, :ethnicity, :gender, :height, :name, :password_digest, :politics, :religion, :sexuality, :user_drink, :user_smoke, :username, :zip_code
  # this prevented user from registering as I don't have timezone select on user reg form
  # validates_inclusion_of :time_zone, in: ActiveSupport::TimeZone.zones_map(&:name)
  has_many :photos
  has_many :letsgos, dependent: :destroy
  belongs_to :default_photo, :class_name => "Photo"
  has_many :notifications
  has_many :questions
  belongs_to :location
  belongs_to :zip
  has_many :messages
  belongs_to :avatar, class_name: 'Photo'
  has_many :received_messages, class_name: 'Message', foreign_key: 'recipient_id'
  has_many :sent_messages, class_name: 'Message', foreign_key: 'sender_id'
  has_many :users, dependent: :destroy
  has_many :relationships, foreign_key: "follower_id", dependent: :destroy
  has_many :followed_users, through: :relationships, source: :followed
  has_many :reverse_relationships, foreign_key: "followed_id", class_name: "Relationship", dependent: :destroy
  has_many :followers, through: :reverse_relationships, source: :follower
  validates_format_of :zip_code,
                  with: /\A\d{5}-\d{4}|\A\d{5}\z/,
                  message: "should be 12345 or 12345-1234"
  validates_uniqueness_of :email
  validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :on => :create
  validates_uniqueness_of :username
  validates_presence_of :username
  validates_format_of :username, :with => /\A[a-zA-Z0-9]+\Z/, :message => "should only contain letters or numbers"
  validates :password, :presence => true,
                       :confirmation => true,
                       :length => {:within => 6..40},
                       :on => :create
  before_create { generate_token(:auth_token) }
  ROLES = %w[admin user guest banned]


  def received_messages
      Message.received_by(self)
    end

 def unread_messages?
   unread_message_count > 0 ? true : false
 end

 def unread_messages
   received_messages.where('read_at IS NULL')
 end

 def sent_messages
   Message.sent_by(self)
 end

 def deleted_messages
   Message.where(recipient_deleted: self)
 end


 # Returns the number of unread messages for this user
 def unread_message_count
   eval 'messages.count(:conditions => ["recipient_id = ? AND read_at IS NULL", self.user_id])'
 end

日志:

2014-02-05T20:46:24Z 36507 TID-107jr10 WARN: {"retry"=>true, "queue"=>"default", "class"=>"UserMessageWorker", "args"=>[152, 1], "jid"=>"68109564031c679162dda497", "enqueued_at"=>1391632954.347344, "error_message"=>"Mysql2::Error: Unknown column 'messages.user_id' in 'where clause': SELECT COUNT(*) FROM `messages`  WHERE `messages`.`user_id` = 1", "error_class"=>"ActiveRecord::StatementInvalid", "failed_at"=>"2014-02-05T20:42:34Z", "retry_count"=>3, "retried_at"=>2014-02-05 20:46:24 UTC}
2014-02-05T20:46:24Z 36507 TID-107jr10 WARN: Mysql2::Error: Unknown column 'messages.user_id' in 'where clause': SELECT COUNT(*) FROM `messages`  WHERE `messages`.`user_id` = 1

【问题讨论】:

    标签: ruby-on-rails sidekiq


    【解决方案1】:

    你的用户模型是什么样的? 编辑:

    您可能需要添加

    usermessages = user.received_messages + user.sent_messages
    

    给你的工作人员并编辑 response_rate 行

    readmessages = []
    usermessages.each do |um|
        if um.read_at != nil
             readmessages << um
        end
    end
    response_rate = (readmessages.count)/(old_msg_count + 1)
    

    如果这有帮助,请告诉我。您可能需要稍微调整一下才能正常工作,但这应该可以解决它

    编辑:

    或者更好,我认为你可以做到这一点

    usermessages = user.received_messages.where("read_at IS NOT NULL").count + user.sent_messages.where("read_at IS NOT NULL").count
    

    并编辑这一行:

    response_rate = usermessages/(old_msg_count + 1)
    

    完整的工人阶级:

    class UserMessageWorker
    include Sidekiq::Worker
    
      def perform(message_id, recipient_id)
        message = Message.find(message_id)
        user = User.find(recipient_id)
        message.read_at = Time.now
        old_msg_count = user.received_messages.count + user.sent_messages.count
        usermessages = user.received_messages.where("read_at IS NOT NULL").count +  user.sent_messages.where("read_at IS NOT NULL").count
    
        if message.save
          msg_response_time = message.read_at - message.created_at
          response_rate = usermessages/(old_msg_count + 1)
          response_time = ((user.average_response_time * old_msg_count)+msg_response_time)/(old_msg_count + 1)
          user.update_attributes(:response_rate => response_rate, :average_response_time => average_response_time )
        end
      end
    end
    

    【讨论】:

    • 添加到用户模型时没有区别。我添加了我的消息模型。
    • 您是否在编辑后重新启动了应用程序?在 Rails 控制台中键入 User.methods 并在其中查找“消息”方法是否存在。
    • 好的,我今天继续这样做,忘记重新启动服务器大声笑。感谢您指出了这一点。它正在 Messages 表中搜索不存在的 user_id,因此我在工作人员内部将其切换为接收者 ID,但它仍以 user_id 读取。使用更新的工作人员向原始帖子添加了错误。
    • 那么你需要这 2 个调用来模拟一个调用 user.received_messages 和 user.sent_messages 并合并这两个数组。还要删除上面的关联,has_many,因为在这种情况下它不起作用。
    • 我现在看到你们的工人阶级了。让我写下工人应该是什么的完整类。
    猜你喜欢
    • 1970-01-01
    • 2013-04-24
    • 2014-12-01
    • 2015-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-12
    • 2013-11-14
    相关资源
    最近更新 更多