【问题标题】:Ruby on Rails model association issueRuby on Rails 模型关联问题
【发布时间】:2013-02-07 21:17:02
【问题描述】:

对不起,标题含糊不清,但一句话解释得有点多。

我有三个模型,用户、设备和设备消息。他们的关系相当简单:

  • 用户has_many :devices
  • 一个设备belongs_to :user
  • 一个设备has_many :device_messages,
  • 和一个 DeviceMessage belongs_to :device

Rails 提供了快速开始使用这些关联的方法,例如获取属于某个用户(从任何设备)的所有设备消息的能力。

为了做到这一点,我在 User 模型中定义了一个方法:

    class User < ActiveRecord::Base
      ...
      has_many :devices, :as => : owner #Other entities may "own" a device

      def device_feed
        DeviceMessage.that_belong_to_user(self)
      end
    end

并且我在DeviceMessage模型中定义了被调用的方法:

    class DeviceMessage < ActiveRecord::Base
      ...
      belongs_to :device

      def self.that_belong_to_user(user)
        device_ids = "SELECT owner_id FROM devices WHERE owner_id = :user_id 
                     AND owner_type = \"User\""
        where("device_id IN (#{device_ids})", user_id: user.id)
      end
    end

我定义了一个用户页面,他们可以在其中将设备与他们的帐户相关联(设备也有一个名称),并且在将设备添加到帐户后,它会将名称添加到窗格中的设备名称列表中在左侧,同时显示用户的设备提要,就像 twitter 提要一样(是的,我遵循了 Michael Hartl 的 RoR 教程)。在这一点上,重要的是要注意我正在使用帮助函数来跟踪当前用户,因此当用户在登录时访问 root_path 时,我可以显示此信息。访问 root_path 时,root_path 的控制器被定义为那:

    if user_signed_in?
      @device_feed_items = current_user.device_feed.paginate(page: params[:page])
    end

这一切都很完美!

那么...有什么问题?当我通过注册页面创建新用户并通过设备关联页面关联设备时,我被重定向到 root_path,设备名称 正确显示在左窗格中(这意味着device 与新用户正确关联),但 device_feed 显示。

我使用 Rails 控制台验证了设备消息应该显示(User.find(2).devices.first.device_messages.first 显示与第一个设备关联的第一条消息,该设备与第二个用户新关联),所以我知道我需要深入数据库以获取 current_user 的新副本而不是缓存副本,但我很困惑,因为每次调用 user.device_feed 方法时似乎都应该发生这种情况,因为它使用where() 是查询 API 的一部分...

有什么想法吗?提前感谢您的任何和所有答案。

-MM

【问题讨论】:

    标签: ruby-on-rails rails-activerecord model-associations


    【解决方案1】:

    我只是想知道为什么你有 device_feed 功能。对于您的提要显示,您是否可以不只是像这样的循环,这是

    class Device < ActiveRecord::Base
    
      scope :in_new_message_order, :joins => :device_messages, :order => "created_at DESC"      
    
    end
    

    添加了一个联合作用域

    class User < ActiveRecord::Base
      ...
      has_many :devices, :as => : owner #Other entities may "own" a device
      scope :in_sort_order, order("message_date DESC")
    
      def device_feed
        DeviceMessage.that_belong_to_user(self)
      end
    end
    

    我在上面添加了一个范围来对您的消息进行排序

    <% user.devices.in_new_message_order.each do |device| %>
        <% device.device_messages_in_sort_order.each do |message| %>
            <%= ....render out the message %>
        <% end %>
    <% end %>
    

    【讨论】:

    • 设备提要将按时间顺序显示所有内容(提要顶部显示最新消息),而提供的方法将简单地按时间顺序打印出消息每个设备,而不是一起。
    • 也许另一种方法是将关系直接从 User 模型添加到 DeviceMessage 模型?喜欢用户has_many :device_messages, through: :devices 什么的...?
    • 刚刚根据您的评论对答案进行了破解,也许它有帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多