SQL到Activerecord:来自连接的伪列?

时间:2011-05-26 06:37:49

标签: sql ruby-on-rails-3 activerecord

我正在教自己这个框架并且一直在搞乱Active Record。我遇到了一个容易用原始SQL解决的问题,我想知道将它移植到Active Record的最佳方法......

我有以下数据库架构......

CREATE TABLE chats (
  id int(11) DEFAULT NULL,
  user_id int(11) DEFAULT NULL,
  more longtext
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE statuses (
  chat_id int(11) DEFAULT NULL,
  user_id int(11) DEFAULT NULL,
  is_read tinyint(1) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE users (
  id int(11) DEFAULT NULL,
  name varchar(255) DEFAULT NULL,
  mail varchar(255) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

我想在Active Record中执行以下操作,其中连接中的1是当前用户ID ...

SELECT 
c.*, s.is_read
FROM chats c
LEFT JOIN statuses s ON c.id = s.chat_id AND 1 = s.user_id

如何设置这种关系,以便在聊天对象中有一个简单的'is read'变量?我知道我可以通过在聊天和状态模型上执行各种逻辑来实现这一点,但这看起来更麻烦了吗?

2 个答案:

答案 0 :(得分:0)

class Chat < ActiveRecord::Base
  has_many :statuses
end

class Status < ActiveRecord::Base
  belongs_to :chat
end

稍后在您的代码中

@chat = Chat.where( 'some where clause' )
@chat.statuses.where( 'some where clause for status' ).is_read

答案 1 :(得分:0)

class Chat
  belongs_to :user
  has_one :status, :through => :user 
  scope :readed, joins(:status).where(:status => {:is_read => true})
  scope :unreaded, joins(:status).where(:status => {:is_read => false})

  delegate :is_read, :to => :status
end

class Status
  belongs_to :user
  belongs_to :chat
end

class User
  has_many :chats
  has_many :statuses
end

@current_user.chats.readed #=> select all user chats where chat status is_read = true
@current_user.chats.unreaded
@current_user.chats.first.is_read