2010-10-20 3 views
0

Я разрабатываю небольшое приложение в Rails 3. В этом приложении пользователи могут быть связаны друг с другом. В основном я использую две таблицы для хранения пользовательских данных и отношений. Я хочу искать эти таблицы с именем или фамилией, чтобы получить контакты пользователя.Поиск с подключением Rails 3

Таблица ONE - Профили

В этой таблице я хранящей ПгвЬЫате, LastName и идентификатор пользователя.

Таблица TWO - Контакты

В этой таблице я хранящий идентификатор (profile_id) пользователя и идентификатор пользователя, он подключен к (friend_id).

Я использую следующий запрос, но он не дает правильных результатов.

Profile.find_by_sql("SELECT * FROM contacts 
       INNER JOIN profiles ON contacts.friend_id = profiles.id WHERE profiles.firstname = '#{@keyword}' OR profiles.lastname = '#{@keyword}'") 

Что не так с is и как оно может быть более эффективным?

ответ

0

Вы можете просто использовать ActiveRecord материал ...

class Profile 
    has_many :contacts, :foreign_key => 'friend_id', :class_name => 'Contact' 
end 

class Contact 
end 

Profile.joins(:contacts).where({:contacts => {:firstname' => 'Cyril', :lastname => 'Mougel'}).all 
+0

Я думаю, что профиль нужен как для контактов, так и для друзей. : контакты будут определяться обычным способом has_many: контакты и: друзья будут вашими: контакты – Jean

+0

это возможно, но на самом деле не очень хороший рельс. Добавить много методов бесполезно – shingara

+0

@Shingara. Я получаю сообщение об ошибке: SQLite3 :: SQLException: нет такого столбца: contacts.firstname: SELECT "profiles". * FROM "profiles" WHERE ("контакты". "Firstname" = 'anders') AND ("контакты". "Lastname "= 'anders') –

1

Три вещи выделяются как «неправильно» с вашим запросом.

Во-первых, вы используете find_by_sql для относительно простого запроса. Если вы собираетесь писать такие запросы по всему вашему приложению, вы можете просто использовать PHP.

Во-вторых, вы передаете параметры запроса в sql. Это оставит вас широко открытыми для SQL-инъекций, поскольку вход не экранирован.

Обе эти проблемы могут быть решены с использованием встроенных методов ActiveRecord. Как указывали некоторые другие ответы, это довольно простой рефактор.

Третья проблема, которую я вижу, не использует стандартные соглашения об именах Rails для внешних ключей. Вместо Contacts.friend_id это должно быть Contacts.profile_id. Это не является обязательным требованием, но чем более условным является ваш код, тем меньше «хаков» вам нужно будет использовать с вашими отношениями модели. Единственным приемлемым исключением из этого правила является то, что вы обновляете существующую схему базы данных, но это не похоже на то, что это ваша ситуация.

Я рекомендую посмотреть на RailsGuides для получения дополнительной информации о стандартных соглашениях.

Смежные вопросы