Почему ruby ​​возвращает тип массива вместо атрибута - PullRequest
0 голосов
/ 13 мая 2011

У меня есть этот код на мой взгляд

<% @items.each do |i| %>
  <tr>
    <td><%= i.name %></td>
  </tr>
<%end%>

и этот код в моем контроллере

  @categories = Category.find_by_sql("SELECT * FROM categories WHERE users_id =#{session[:user_id]}")
  @categories.each do |c|
    @items << (Item.where(:categorys_id => c.id))
  end

и когда я запускаю его, код генерирует страницу, похожую на эту: «Ваше имя пользователя является предметом предмета» вместо "Ваше имя пользователя - Цифровая Крепость Океанов Одиннадцать Поселенцев"

Ответы [ 3 ]

2 голосов
/ 13 мая 2011

То, чего вы пытаетесь достичь, можно сделать так:

Item.where (: categoryor__id => c.id). первый

Item.where возвращает область, фактически не создает и не выполняет запрос.

Методы first и last запустят запрос с LIMIT и ORDER BY и вернут элемент.

Методы типа each и all создают и запускают запрос и возвращают массив результатов.

Проверка кода

Код вашего контроллера подвержен внедрению SQL, изображение, если в session[:user_id] было что-то злое. "#{stuff}" не делает экранирования stuff в Ruby.

Чтобы избавиться от проблемы с впрыском:

ruby @categories = Category.where(:users_id => session[:user_id]) # Are you sure the column is not user_id but users_id?

Второе, что мы должны сделать, - это избегать выполнения N + 1 запроса, где N - количество результирующих категорий.

Хороший способ сделать это - использовать оператор SQL IN. ruby @items = Item.where(:categorys_id => @categories.map(&:id)) #

1 голос
/ 13 мая 2011

Я бы переписал код вашего контроллера следующим образом:

@categories = Category.find_all_by_user_id(session[:user_id], :include => :items)
@items      = @categories.map(&:items).flatten

Теперь, на ваш взгляд:

<% @items.each do |item| %>
  <tr>
    <td><%= item.name %></td>
  </tr>
<%end%>
0 голосов
/ 13 мая 2011

Item.where(:categorys_id => c.id) даст вам объект ActiveRecord, а не отдельные атрибуты.Поэтому, когда вы выполняете итерацию над ними, i является объектом Item, а не атрибутом.

Допустим, вы действительно хотите вывести поле name элемента, тогда вы сделаете это:

<% @items.each do |i| %>
  <tr>
    <td><%= i.name %></td>
  </tr>
<%end%>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...