Ruby on rails 即使外键有效,Rails也属于返回nil 总结
我遇到了一个问题,我的Ruby on rails 即使外键有效,Rails也属于返回nil 总结,ruby-on-rails,foreign-keys,associations,Ruby On Rails,Foreign Keys,Associations,我遇到了一个问题,我的所属关联正在返回nil,而我认为它不应该返回 我想做什么 ChannelUser应该能够从相关的channel返回消息,其中在处创建的大于其用户上次从该频道读取的时间。类别定义如下: class ChannelUser{includes(:通道)} def未读消息 channel.messages.where('created\u at>?',last\u read\u at) 结束 结束 类用户{includes(:channel)},依赖::destroy 拥有多个:频
所属
关联正在返回nil
,而我认为它不应该返回
我想做什么
ChannelUser
应该能够从相关的channel
返回消息,其中在处创建的大于其用户上次从该频道读取的时间。类别定义如下:
class ChannelUser{includes(:通道)}
def未读消息
channel.messages.where('created\u at>?',last\u read\u at)
结束
结束
类用户<应用程序记录
拥有多个:channel用户,->{includes(:channel)},依赖::destroy
拥有多个:频道,通过::频道用户
有很多:信息
结束
类通道<应用程序记录
拥有多个:通道用户,依赖::销毁
拥有多个:用户,通过::通道用户
有很多:消息,->{order(在::asc创建)。limit(100)},dependent::destroy
结束
类消息<应用程序记录
属于:频道
属于:用户
有丰富的文本:body
...
结束
我试图呈现来自用户在视图中加入的所有频道的未读邮件总数:
User
类有有许多:频道用户
和有许多:频道,通过::频道用户
。Channel
类有有许多:Channel\u用户
和有许多:用户,通过::Channel\u用户
问题
当我使用任何ChannelUser
实例在rails控制台中执行unread\u messages
方法时,我没有收到任何错误。但是,当我在开发中运行应用程序时,我得到:
正如您在图片底部的web控制台中所看到的,channel
返回nil
,即使channel\u id
是有效的外键。事实上,模式的定义如下:
class CreateChannelUsers
我还使用
在视图中放置了一个断点,并查看了当前用户
、当前用户、频道用户和当前用户、频道用户的值。首先,未读消息
。对于current_user
,我获得了与我的登录帐户关联的user
实例。对于current\u user.channel\u users
,我获得了代表我加入的聊天频道的记录。对于curretn\u user.channel\u users.first.unread\u messages
,我没有收到错误,我得到一个空的关系集,正确地标识我没有任何未读消息。重要的是要注意,当我没有聚合所有未读邮件的总和时,不会发生此错误
更新
我发现我可以通过单击调用堆栈中的行来更改web控制台的范围,因此下面是web控制台的更多输出:
>> current_user.channel_users
=> #<ActiveRecord::Associations::CollectionProxy [#<ChannelUser id: 7, channel_id: 5, user_id: 1, created_at: "2020-11-09 06:42:52", updated_at: "2020-11-15 23:44:28", last_read_at: "2020-11-15 23:44:28">, #<ChannelUser id: 3, channel_id: 4, user_id: 1, created_at: "2020-11-09 06:26:12", updated_at: "2020-11-09 06:27:03", last_read_at: "2020-11-09 06:27:03">, #<ChannelUser id: 4, channel_id: 6, user_id: 1, created_at: "2020-11-09 06:30:41", updated_at: "2020-11-15 23:32:26", last_read_at: "2020-11-15 23:32:26">, #<ChannelUser id: 8, channel_id: 7, user_id: 1, created_at: "2020-11-10 01:20:44", updated_at: "2020-11-15 23:33:24", last_read_at: "2020-11-15 23:33:24">]>
>> current_user.channel_users.map(&:unread_messages)
NoMethodError: undefined method `messages' for nil:NilClass
from /home/jakehockey10/Code/team-portal/app/models/channel_user.rb:29:in `unread_messages'
from /home/jakehockey10/Code/team-portal/app/views/dashboard/show.html.erb:9:in `map'
from /home/jakehockey10/Code/team-portal/app/views/dashboard/show.html.erb:9:in `_app_views_dashboard_show_html_erb___259171981150348787_116880'
>> current_user.channel_users.first.unread_messages
NoMethodError: undefined method `messages' for nil:NilClass
from /home/jakehockey10/Code/team-portal/app/models/channel_user.rb:29:in `unread_messages'
from /home/jakehockey10/Code/team-portal/app/views/dashboard/show.html.erb:9:in `_app_views_dashboard_show_html_erb___259171981150348787_116880'
>> current_user.channel_users.first
=> #<ChannelUser id: 7, channel_id: 5, user_id: 1, created_at: "2020-11-09 06:42:52", updated_at: "2020-11-15 23:44:28", last_read_at: "2020-11-15 23:44:28">
>> current_user.channel_users.first.channel
=> nil
>> Channel.find(5)
=> #<Channel id: 5, name: "general", account_id: 2, created_at: "2020-11-09 06:30:32", updated_at: "2020-11-09 06:30:32", direct_message: false>
另一个更新
这是蛋糕上的糖霜:
我不知道这是怎么回事,我想知道这是否是某种名称冲突问题或其他什么。如何诊断
更新
同样的问题,尝试不同的方法:
为什么它会在这一行抛出错误,但如果我将同一行粘贴到web控制台的错误页面上,它不会抛出错误?我遗漏了什么?尝试删除包含的内容,我不是100%确定,但这可能是潜在的问题
class User < ApplicationRecord
has_many :channel_users, dependent: :destroy
class用户
您可以用替换模型中的包括
我95%确信问题来自消息模型
似乎channel.messages不等于channel.user.messages。
首先,您没有在问题中向我们展示消息的模型,请更新问题
其次,您有两个模型:频道和用户,它们都与消息模型有关联(有许多:消息
),而对我来说,这并不是很好的关联(在看到消息模型之前,我无法了解解决方案)
第三,在您的查询中:
User.first.channel_users.sum(&:unread_messages)
其中一行:
Message Load (0.4ms) SELECT "messages".* FROM "messages" WHERE "messages"."channel_id" = $1 AND (created_at > '2020-11-15 23:44:28.787257') ORDER BY "messages"."created_at" ASC LIMIT $2 [["channel_id", 5], ["LIMIT", 100]]
Message Load (0.2ms) SELECT "messages".* FROM "messages" WHERE "messages"."channel_id" = $1 AND (created_at > '2020-11-09 06:27:03.105358') ORDER BY "messages"."created_at" ASC LIMIT $2 [["channel_id", 4], ["LIMIT", 100]]
Message Load (0.2ms) SELECT "messages".* FROM "messages" WHERE "messages"."channel_id" = $1 AND (created_at > '2020-11-15 23:32:26.070403') ORDER BY "messages"."created_at" ASC LIMIT $2 [["channel_id", 6], ["LIMIT", 100]]
Message Load (0.2ms) SELECT "messages".* FROM "messages" WHERE "messages"."channel_id" = $1 AND (created_at > '2020-11-15 23:33:24.022821') ORDER BY "messages"."created_at" ASC LIMIT $2 [["channel_id", 7], ["LIMIT", 100]]
例如,第一行类似于:
Message Load (0.4ms) SELECT "messages".* FROM "messages" WHERE "messages"."channel_id" = 5 AND (created_at > '2020-11-15 23:44:28.787257') ORDER BY "messages"."created_at" ASC LIMIT 100
这意味着:获取100条已排序的消息,其通道id=5。这个返回空值!或空消息集
因此,我的问题就来自于此。我终于解决了这个问题。在此应用程序中,为了提供多租户,每个用户都有一个关联的帐户。账户可以是个人账户,也可以是非个人账户。登录后,您可以将视角从个人帐户更改为与您关联的任何非个人帐户。然后,具有account\u id
列的资源将被过滤为当前帐户。这种过滤发生在中间件中,因此与执行实际查询的代码分离
当我第一次开始实现此功能时,我在尝试将通道(作为一个整体功能)限制为非个人帐户上下文之前,在我的个人帐户上创建了一些通道。因此,我的数据库中有一些与个人账户相关的渠道
在我的屏幕截图中,应用程序使用该中间件将频道限制为具有特定当前帐户id的频道。但当我在web控制台或rails控制台中模拟相同的查询时,显然没有运行中间件来过滤当前帐户的内容
Message Load (0.4ms) SELECT "messages".* FROM "messages" WHERE "messages"."channel_id" = 5 AND (created_at > '2020-11-15 23:44:28.787257') ORDER BY "messages"."created_at" ASC LIMIT 100