总之,我的视图中有一些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)%>
供参考我的对话控制器索引操作:
def index
@profiles = Profile.all
@conversations = Conversation.involved(current_user.profile.id)
end
我的谈话模型
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
这是我的第一个stackoverflow问题,所以如果我没有关注此问题的任何最佳做法,请告诉我们!
答案 0 :(得分:1)
欢迎使用StackOverflow!
在这种情况下,您只是根据是否conversation.sender == current_user
打印个人资料的名称。在Conversation
模型上,您可以使用:display_name
方法接收用户。
def display_name(profile)
(sender == profile ? recipient : sender).name
end
这是表示方法,所以它可能更适合Helper,Presenter,Decorator或许多其他解决方案,但这应该可以解决问题。在您的观看中,请致电:link_to conversation.display_name(current_user.profile), ...
答案 1 :(得分:1)
就个人而言,我会说你的if / else逻辑适合于一个视图;它是每个块中最好避免的查询。你基本上有什么称为n + 1查询(你在@conversations
中有n个对象,你在数据库中查询每个对象的Profile对象,并且你的原始查询填充@conversations,因此n +1)。
在控制器中,您可以像这样加载发件人和收件人:
scope :involved_with_profiles -> (user) do
includes(:sender, :recipient).where(...same logic as your :involved scope...)
end
使用此范围代替:involved
加载@conversations
。然后你可以在视图中保留你的if / else逻辑,但不是查询一个Profile,你可以这样做:
<% recipient = conversation.recipient %>
或
<% recipient = conversation.sender %>
因为这些已经从单个查询加载到@conversations。
答案 2 :(得分:0)
它很好。
将它放在帮手中除了可以在其他地方重复使用外,不会给你任何东西。