在rails上的ruby中一次更新多个属性

时间:2012-02-17 11:45:10

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-3.1 rubygems

我有一个页面,用户可以在当前线程会话中查看消息列表。

他们可以使用删除链接(每个消息的每个循环内的链接)删除每封邮件:

<%= link_to 'Delete', message, :method => :delete, :confirm => "Are you sure?", :title => message.body %> <br />

这基本上将它们连接到我的messages_controller中的一个动作:

  def destroy

  @message = Message.find(params[:id])
  @message.update_attribute('sender_status', 1) if @message.sender_id == current_user.id
  @message.update_attribute('recipient_status', 1) if @message.recipient_id == current_user.id
  @message.destroy if @message.sender_status == 1 && @message.recipient_status == 1

  flash[:success] = "Message deleted"
    redirect_to :back
  end

我现在想要的是在所有消息之前的一个链接(所以我不会把它放在每个块中)。此链接将被称为“全部删除”,而不是使用值1更新1属性,它将所有属性(sender / recipient_status)更新为1,这样用户就不必单击每个单独的消息删除链接。 / p>

我有点担心如何做到这一点。我不使用复选框,而是删除链接,所以对于删除所有我宁愿也使用链接。

任何机构能为我提供一个解决方案吗?我真的很感激。我以为我昨晚睡在上面,早上有个主意但仍然没有想到。

亲切的问候

更新

消息属于对话。我可以通过以下方式获取对话: 1)MessageThread表。这将第一个消息的message_id存储在会话中,该会话是该会话中其他消息的parent_id。例如。

+-----+----------+---------+---------+---------+--------+---------+----------+----------+----------+
| id  | sende... | reci... | body    | pare... | status | crea... | updat... | sende... | recip... |
+-----+----------+---------+---------+---------+--------+---------+----------+----------+----------+
| 220 | 4        | 1       | hi      | 220     | 0      | 2012... | 2012-... | 0        | 0        |
| 221 | 1        | 4       | hey     | 220     | 0      | 2012... | 2012-... | 0        | 0        |
| 222 | 4        | 1       | hi      | 220     | 0      | 2012... | 2012-... | 0        | 0        |
| 223 | 1        | 4       | hi      | 220     | 0      | 2012... | 2012-... | 0        | 0        |
| 232 | 1        | 4       | good    | 220     | 0      | 2012... | 2012-... | 0        | 0        |
| 233 | 4        | 1       | and ... | 220     | 0      | 2012... | 2012-... | 0        | 0        |
| 237 | 1        | 4       | hmm     | 220     | 0      | 2012... | 2012-... | 0        | 0        |
| 238 | 1        | 4       | yay     | 220     | 0      | 2012... | 2012-... | 0        | 0        |
| 239 | 1        | 4       | yess    | 220     | 0      | 2012... | 2012-... | 0        | 0        |

2)我也可以通过父ID找到对话。例如m = Message.find_by_parent_id(220)。

要获取convo中的其他消息,我只需输入m.children

以下是我的messagethreads表的外观:

+-----+------------+-----------+--------------+--------+---------------------+---------------------+
| id  | message_id | sender_id | recipient_id | status | created_at          | updated_at          |
+-----+------------+-----------+--------------+--------+---------------------+---------------------+
| 102 | 247        | 1         | 5            | 0      | 2012-02-16 16:18... | 2012-02-16 16:18... |
| 101 | 246        | 1         | 3            | 0      | 2012-02-16 16:14... | 2012-02-16 16:14... |
| 90  | 220        | 4         | 1            | 0      | 2012-02-15 14:05... | 2012-02-15 14:05... |
| 89  | 219        | 4         | 38           | 0      | 2012-02-15 12:26... | 2012-02-15 12:26... |
| 88  | 218        | 2         | 4            | 0      | 2012-02-14 13:41... | 2012-02-14 13:41... |
| 87  | 210        | 1         | 2            | 0      | 2012-02-14 13:31... | 2012-02-14 13:31... |
+-----+------------+-----------+--------------+--------+---------------------+---------------------+

以下是对我有用的内容:

 def destroy_all_messages

  Message.find_by_parent_id(params[:format]).children.each do |message|
    message.update_attribute('sender_status', 1) if message.sender_id == current_user.id
    message.update_attribute('recipient_status', 1) if message.recipient_id == current_user.id
    message.destroy if message.sender_status == 1 && message.recipient_status == 1
  end
        flash[:success] = "Messages deleted"
    redirect_to :back
end

<%= link_to 'Delete All', messages_delete_all_messages_path(@current_thread.message_id), :method => :delete, :confirm => "Are you sure?" %> <br />

这对我有用..意见? 我注意到我必须使用“params [:format]”来获取我传入控制器中link_to消息路径的参数。

3 个答案:

答案 0 :(得分:2)

使用'update_attributes'方法,并将要更新的字段作为哈希值传递。

答案 1 :(得分:2)

Thorsten是现场。

我可以建议额外清理吗?

Message.rb

def is_deletable?(current_user)
   if (self.sender_status == 1 || self.sender_id == current_user.id) &&
       (self.recipient_status == 1 || self.recipient_id == current_user.id)
     true
   else
     false
   end
end

message_controller.rb

def destroy
  @message = Message.find(params[:id])
  if @message.is_deletable?(current_user)
   @message.destroy 
   flash[:success] = "Message deleted"
  else
   flash[:error] = "You dont have permission to delete this message"
  end
  redirect_to :back
end

def destroy_messages

 Message.find_by_parent_id(params[:id]).each do |message|
  message.destroy if message.is_deletable?(current_user)
 end
 flash[:success] = "Deleted all permissible messages"
 redirect_to :back
end

这样做的另一个好处是可以将一个额外的更新语句添加到您即将删除的行中,因此应该让事情变得更快。效率更高。

答案 2 :(得分:1)

这些邮件是如何分组的?他们属于对话吗?

如果是对话(使用has_many:消息)您可以向对话中添加“删除所有消息”按钮,该会话将此对话的ID发送到delete_messages操作。在这个动作中做

def destroy_messages

  Conversation.find(params[:id]).messages.each do |message|
    message.update_attribute('sender_status', 1) if message.sender_id == current_user.id
    message.update_attribute('recipient_status', 1) if message.recipient_id == current_user.id
    message.destroy if message.sender_status == 1 && message.recipient_status == 1
  end
end

可能需要一些细节才能获得适当的授权。如果没有Conversation模型,请在搜索要删除的消息后执行类似操作。 (或者告诉我们一些细节你究竟展示了什么,以及你决定如何展示它)

<强>更新

这应该是一样的。如果您可以轻松获取所有消息,只需将“对话”替换为父消息即可。您链接应发送父消息的ID,然后运行其所有子消息并更新其状态。应该很容易。

m = Message.find(params[:id])
m.children.each do |message|
    ... as above ...
end

一般情况下,只需发送一个标识符(本例中为父标识),该标识符足以识别要删除的邮件,使用它来运行查找,然后更新记录。