Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails:将逻辑移出视图_Ruby On Rails_Views_Messaging - Fatal编程技术网

Ruby on rails Rails:将逻辑移出视图

Ruby on rails Rails:将逻辑移出视图,ruby-on-rails,views,messaging,Ruby On Rails,Views,Messaging,简言之,我的视图中有一些if/else逻辑,我认为作为控制器方法或助手会更有效。也就是说,我不确定将其转化为一种方法的最佳方式是什么,也不确定将其置于何处 我正在我的Rails应用程序中构建一个用户消息系统。在我的应用程序中,一个配置文件有许多对话(两个配置文件之间),其中包含许多消息。我正试图建立一个会话索引,它基本上就像一个收件箱。作为Rails初学者,我不太确定将if/else部分移出视图的最有效/最好的方法是什么,因为它在.each循环中运行。现在我的观点是这样的: <% @con

简言之,我的视图中有一些if/else逻辑,我认为作为控制器方法或助手会更有效。也就是说,我不确定将其转化为一种方法的最佳方式是什么,也不确定将其置于何处

我正在我的Rails应用程序中构建一个用户消息系统。在我的应用程序中,一个配置文件有许多对话(两个配置文件之间),其中包含许多消息。我正试图建立一个会话索引,它基本上就像一个收件箱。作为Rails初学者,我不太确定将if/else部分移出视图的最有效/最好的方法是什么,因为它在.each循环中运行。现在我的观点是这样的:

<% @conversations.each do |conversation| %>
<% if conversation.sender_id == current_user.profile.id %>
  <% recipient = Profile.find(conversation.recipient_id) %>
<% else %>
  <% recipient = Profile.find(conversation.sender_id) %>
<% end %>
<%= link_to recipient.first_name, conversation_messages_path(conversation)%>
还有我的对话模式

class Conversation < ActiveRecord::Base
  belongs_to :sender, :foreign_key => :sender_id, class_name: 'Profile'
  belongs_to :recipient, :foreign_key => :recipient_id, class_name: 'Profile'
  has_many :messages, dependent: :destroy
  accepts_nested_attributes_for :messages

  validates_uniqueness_of :sender_id, :scope => :recipient_id

  scope :between, -> (sender_id,recipient_id) do
   where("(conversations.sender_id = ? AND conversations.recipient_id =?) OR (conversations.sender_id = ? AND conversations.recipient_id =?)", sender_id,recipient_id, recipient_id, sender_id)
  end

  scope :involved, -> (user) do
   where("(conversations.sender_id = ? OR conversations.recipient_id =?)", user, user)
  end
end
类对话:sender\u id,class\u name:'Profile'
属于:收件人,:外键=>:recipient\u id,类名称:'Profile'
有很多:消息,依赖::销毁
接受消息的\u嵌套\u属性\u
验证以下项的唯一性:发送方\u id,:范围=>:接收方\u id
范围:介于,->(发送方id、接收方id)之间
其中(“(conversations.sender\u id=?和conversations.recipient\u id=?)或(conversations.sender\u id=?和conversations.recipient\u id=?)”,发件人\u id,收件人\u id,收件人\u id,发件人\u id)
结束
范围:涉及,->(用户)do
其中(((conversations.sender\u id=?或conversations.recipient\u id=?)”,用户,用户)
结束
结束

这是我的第一个stackoverflow问题,所以如果我没有遵循这个问题的任何最佳实践,请让我知道

欢迎来到StackOverflow

在这种情况下,您只需根据是否
conversation.sender==current_user
打印配置文件的名称。在您的
对话
模型上,您可以有一个接收用户的
:display_name
方法

def display_name(profile)
  (sender == profile ? recipient : sender).name
end

这是一种表示方法,因此它可能更适合于助手、演示者、装饰者或其他许多解决方案,但这应该可以做到。在您的视图中,可以这样称呼它:
链接到对话。显示名称(当前用户配置文件),…

我个人认为您的if/else逻辑适合于视图;最好避免的是每个块中的查询。实际上,您有所谓的n+1查询(您在
@conversations
中有n个对象,您在数据库中查询每个对象的概要文件对象,您的原始查询填充@conversations,因此是n+1)

在控制器中,您可以按如下方式加载发件人和收件人:

scope :involved_with_profiles -> (user) do
  includes(:sender, :recipient).where(...same logic as your :involved scope...)
end
使用此作用域而不是
:included
来加载
@conversations
。然后,您可以在视图中保留if/else逻辑,但不必查询配置文件,只需执行以下操作:

<% recipient = conversation.recipient %>


因为这些已经从一个查询加载到@conversations中。

在哪里都可以


将它放在助手中不会给您带来任何好处,只能在其他地方获得可重用性。

谢谢Michael。如果有机会,您是否介意澄清一下您的范围中的“包含”部分与我最初的
:涉及的
范围相比在做什么?它是否消除了每个if/else检查对数据库的额外访问?还是我弄错了?当然。它只是在原始查询中包含这些关联,以便将它们与对话对象本身一起加载到内存中。然后,当您在循环中引用它时,它不必查询数据库中的关联数据——它已经在内存中了。这称为即时加载。感谢Leito,仅供参考,我必须使用
链接到对话。显示名称(当前用户.配置文件)
,因为对话连接到配置文件而不是用户对象。我想这对大多数人来说可能是显而易见的,但它使用三元运算符创建了一些奇怪的场景,因为在某些情况下,配置文件ID和用户ID匹配,而在其他情况下,它们不匹配。对于像我这样的初学者来说,这让事情变得不那么明显。接得好,我很高兴你找到了解决这个问题的办法。如果你退后一步,用户id匹配配置文件id并抛出一个不想要的结果一点也不奇怪。我们问了鲁比一个错误的问题。假设当前用户是一个配置文件实例是我的错。我不同意,它在它所在的位置工作,但视图做出这个决定是不好的。我们不同意。尊重,你们保持你们的立场,同时保持礼貌,如果我们都这么做的话,互联网会是一个更好的地方!我(你开始说服我)正在考虑“告诉别人不要问”的原则(简称:)。视图不必知道
Conversation
的内部逻辑就可以显示用户,它只需询问告诉该对话显示给哪个用户即可。但这取决于当前用户,因此它应该位于仅处理持久性的模型之外。
<% recipient = conversation.recipient %>
<% recipient = conversation.sender %>