Преобразование инструкции SQL в Ruby on Rails

#ruby-on-rails #sql-server #ruby #ruby-on-rails-3 #sql-server-2008

#ruby-on-rails #sql-сервер #ruby #ruby-on-rails-3 #sql-server-2008

Вопрос:

У меня есть две таблицы, и я хочу сравнить данные между ними и выбрать данные из одной таблицы, которых нет в другой. У меня уже есть код, который работает в управлении SQL Server, но мне нужно преобразовать его в 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
)
  

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

Комментарии:

1. И у вас есть модель для App_Servers или вы начинаете с нуля?

Ответ №1:

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

 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
      )
")
  

Комментарии:

1. Можно привести аргумент в пользу того, что вы всегда должны, по крайней мере, пытаться перевести свой sql в AREL. Это заставляет мою голову немного кружиться, потому что я не знаю о моделях и возможных ассоциациях здесь. Я не говорю, что не делайте того, что вы предлагаете, но я бы сначала попробовал использовать синтаксис запроса ActiveRecord. руководство по Arel

2. Я согласен с вами, возможно, в этом конкретном случае не так много пользы, но в целом это действительно удобно. Итак, смотрите Обновление.

3. @Bohdan Pohorilets приятно, что это сработало для меня 😉 Я попробую внести изменения без select * from app_servers этого и дам вам знать.

Ответ №2:

Если я правильно понимаю, у вас есть две модели, 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)
  

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

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

 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.
Но я показал несколько способов, позволяющих использовать некоторые помощники rails, и, во-вторых, кажется хорошим подходом, если это возможно (даже с использованием представлений), преобразовать вашу модель данных в более удобную для rails модель. Одна из веских причин заключается в том, что rails-способ создания моделей данных на самом деле является довольно хорошим способом.

Комментарии:

1. Вау, это круто, чувак. Большое спасибо за помощь. Удалось запустить его и запустить через справку @Bohdan Pohorilets, но, несмотря на это, я обязательно посмотрю на ваш ответ и повторно использую его в будущем 😉