【问题标题】:Updating more than one attribute at one time in ruby on rails在 ruby​​ on rails 中一次更新多个属性
【发布时间】:2012-02-17 11:45:09
【问题描述】:

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

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

<%= 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 个属性,它会将所有属性(发件人/收件人状态)更新为 1,这样用户就不必单击每个单独的消息删除链接。

我有点不知道该怎么做。我不使用复选框,而是删除链接,所以对于删除所有我宁愿使用链接。

任何机构可以通过示例为我提供解决方案吗?我真的很感激。昨晚以为我会睡在上面,早上有一个想法,但仍然没有想到。

亲切的问候

更新

消息属于对话。我可以通过以下方式进行对话: 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 消息路径的参数。

【问题讨论】:

  • 我猜应该有一个与当前对话线程相关的实体,例如conversation 记录。如果是,则传递对话记录 ID,找出该对话的所有消息以删除。
  • 在我的帖子中添加了更多信息

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


【解决方案1】:

改用“update_attributes”方法,并将您要更新的字段作为哈希传递。

【讨论】:

    【解决方案2】:

    Thorsten 在现场。

    我可以建议进行额外的清理吗?

    消息.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
    

    这有一个额外的好处,即向您即将删除的行添加额外的更新语句,因此应该使事情变得更快、更高效。

    【讨论】:

    • 这是一个很好的清理。我只是让事情正常工作,然后最终要检查我的整个项目并清理代码......从控制器中取出实际上可能在模型中的东西。你的例子看起来很不错。
    【解决方案3】:

    这些消息是如何分组的?它们属于对话吗?

    如果是对话(使用 has_many :messages),您可以在对话中添加“删除所有消息”按钮,将对话的 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
    

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

    更新

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

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

    一般来说,只需发送一个足以识别要删除的消息的标识符(在这种情况下为父 ID),使用它来运行查找,然后更新记录。

    【讨论】:

    • 您好在我的帖子中添加了一些信息。有两种方法可以抓住对话。
    猜你喜欢
    • 2014-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多