Bulk updating a joined table with ActiveRecord upd

2019-08-31 02:48发布

问题:

I have a PostgreSQL query that I would like to write in ActiveRecord (Rails 4), but I'm having trouble getting it to work correctly.

UPDATE chats AS c
SET email = m.source_name
FROM messages AS m
WHERE c.id = m.chat_id 
  AND m.created_at >= '2014-10-10'

This is what I've tried:

Chat.joins(:messages)
  .where("message.created_at >= '2014-10-10'")
  .update_all('chat.email = message.source_name')

But it creates a query like this:

UPDATE "chats" 
SET chat.email = message.source_name 
WHERE "chats"."id" IN (
  SELECT "chats"."id" 
  FROM "chats" 
  INNER JOIN "messages" 
    ON "messages"."chat_id" = "chats"."id" 
  WHERE (message.created_at >= '2014-10-10')
)

Any help on this?

回答1:

Since Chat.update_all will add UPDATE chats SET... the only way that I can think of get rails to do an update with an alias (UPDATE chats AS c) is by using connection.update and a sql string:

Chat.connection.update(Q%{
  UPDATE chats AS c 
  SET email = m.source_name
  FROM messages AS m
  WHERE c.id = m.chat_id 
    AND m.created_at >= '2014-10-10'
});

Not great if you want to avoid SQL fragments, but using an a join as in your question may be the only way if you want to use AREL.