Конвертировать оператор SQL в Ruby on Rails - PullRequest
0 голосов
/ 03 октября 2011

У меня есть две таблицы, и я хочу сравнить данные между ними и выбрать данные из одной таблицы, которой нет в другой.У меня уже есть код, который работает в SQL Server Management, но мне нужно преобразовать его в Rails, или я должен иметь возможность использовать сырой код SQL в своем коде.Вот код:

select * from app_servers
where not exists 
( select app, environment, server 
            from stagings
            where stagings.server = app_servers.server_id
            AND
            stagings.environment = app_servers.environment_id 
            AND 
            app_servers.app_id = stagings.app
)

Заранее спасибо

Ответы [ 2 ]

6 голосов
/ 03 октября 2011

Почему вы хотите конвертировать это? Вы можете использовать его как

AppServer.where(" not exists 
      ( select app, environment, server 
        from stagings
        where stagings.server = app_servers.server_id
        AND
        stagings.environment = app_servers.environment_id 
        AND 
        app_servers.app_id = stagings.app
      )
")
5 голосов
/ 03 октября 2011

Если я правильно понимаю, у вас есть две модели, AppServer и Staging, и у обеих есть среда, сервер и приложение. Вы ищете AppServer, которые не имеют Staging.

Итак, ваши модели будут выглядеть так:

class AppServer
  belongs_to :server
  belongs_to :environment
  belongs_to :app
end

class Staging
  belongs_to :server
  belongs_to :environment
  belongs_to :app
end

Но то, что вы на самом деле хотели бы, это что-то вроде

class AppServer 
  belongs_to :server
  belongs_to :environment
  belongs_to :app
  has_one :staging
end

, который было бы действительно легко проверить. Что-то вроде:

AppServer.where(:staging_id => nil)

Так что вы можете подумать о реформировании вашей модели данных, чтобы сделать это проще. Это не будет слишком сложно: добавьте один столбец, и для каждого сервера приложений найдите соответствующую организацию.

Но предположим, что вы не имеете никакого контроля над своей моделью данных, вам нужно написать что-то вроде

class AppServer
  has_many :stagings, finder_sql => 'select * from stagings where server=#{server_id} and environment=#{environment_id} and app=#{app_id}'

Примечание: вы должны использовать одинарные кавычки! Это по крайней мере позволит вам получить доступ к что-то вроде

app_server = AppServer.first
app_server.stagings

К сожалению, он не позволяет писать что-то вроде

AppServer.where(:stagings => nil)

Чтобы найти все AppServer без постановки, и вы не можете преобразовать схему, вам нужно будет сделать что-то вроде

AppServer.where(" not exists 
  ( select app, environment, server 
    from stagings
    where stagings.server = app_servers.server_id
    AND
    stagings.environment = app_servers.environment_id 
    AND 
    app_servers.app_id = stagings.app
  )"
)

Так что на самом деле, в конце концов, я не нашел нового и улучшенного способа использования arel. Но я показал некоторые способы разрешить использование некоторых помощников рельсов, и, во-вторых, это хороший способ, если это возможно (даже с использованием представлений), преобразовать вашу модель данных в более подходящую для рельсов модель. Одна веская причина в том, что метод создания моделей данных на самом деле довольно хороший.

...