Новичок в рельсах. Индексному действию не нравится мой метод инициализации. Почему?

Я совершенно новичок в рельсах и играю с кодом, чтобы заставить страницы работать. Ссылка localhost:3000/zombies/1 работает (показать действие), но localhost:3000/zombies (индексное действие) — нет. Ниже приведены мои маршруты и контроллер:

МАРШРУТЫ: ресурсы :зомби

КОНТРОЛЛЕР:

 class ZombiesController < ApplicationController
    before_filter :get_zombie_params

   def index
    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @zombies }
    end
   end

   def show
    @disp_zombie = increase_age @zombie, 15
    @zombie_new_age = @disp_zombie
    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @zombie }
    end
  end

  def increase_age zombie, incr
   zombie = zombie.age + incr
  end

  def get_zombie_params
    @zombie=Zombie.find(params[:id])
    @zombies = Zombie.all

  end
end

Почему это?


person user836087    schedule 23.10.2012    source источник
comment
Вы можете вставить ошибку, которую вы получаете?   -  person ryan0    schedule 24.10.2012
comment
Ваш код выглядит хорошо для меня. Что на самом деле происходит, когда вы переходите к /zombies/? Выбрасывается ли исключение? Вы получаете пустую страницу? Дополнительная информация поможет нам помочь вам!   -  person alexpls    schedule 24.10.2012
comment
Я получаю страницу с ошибкой: ActiveRecord::RecordNotFound in ZombiesController#index Не удалось найти зомби без идентификатора Rails.root: C:/Sites/TwitterForZombies Application Trace | трассировка фреймворка | Приложение полной трассировки/controllers/zombies_controller.rb:85:in `get_zombie_params'   -  person user836087    schedule 24.10.2012
comment
Проблема в том, что вы используете этот фильтр before_filter на обоих маршрутах. На шоу вы можете звонить как Zombie.find(params[:id]), так и Zombie.all. Но в действии index у вас нет никаких параметров, поэтому ваш Zombie.find(params[:id] выдает вам ошибку ActiveRecord.   -  person mehulkar    schedule 24.10.2012
comment
Спасибо, Мехул. Есть ли способ обойти это? Я хочу инициализировать переменные экземпляра зомби и зомби в отдельном методе перед.   -  person user836087    schedule 24.10.2012


Ответы (3)


Редактирование ответа на основе комментария

Я получаю страницу с ошибкой: ActiveRecord::RecordNotFound в ZombiesController#index Не удалось найти зомби без идентификатора Rails.root: C:/Sites/TwitterForZombies Application Trace | трассировка фреймворка | Приложение полной трассировки/controllers/zombies_controller.rb:85:in `get_zombie_params'

URL-адрес localhost:3000/zombies, который вызывает действие index, не включает параметр id.

Вот почему приложение не работает на @zombie=Zombie.find(params[:id]).

Если вы хотите решить эту проблему, используйте before_filter только для действия show.

before_filter :get_zombie_params, only: :show

И вставьте это в действие index, как я первоначально предложил.

def index
  @zombies = Zombies.all
  ...
end
person Jason Kim    schedule 23.10.2012
comment
Это не проблема — @zombies уже назначен в before_filter - person alexpls; 24.10.2012
comment
да. Об этом уже должен позаботиться предварительный фильтр. - person user836087; 24.10.2012

Это происходит потому, что когда вы определяете resources :zombies, вы получаете следующие маршруты:

/zombies
/zombies/:id

Поэтому при переходе к /zombies у вас нет params[:id], это nil

Zombie.find вызовет ошибку, если не сможет найти ни одной записи с заданным идентификатором, и остановит дальнейшую обработку вашего кода.

Вы можете использовать Zombie.find_by_id, если вы не хотите, чтобы возникало исключение, когда нет результата.

Но я не думаю, что это то, что вы хотите здесь, вы бы скорее определили метод get_zombie_by_id и метод get_all_zombies и отделили код от вашего get_zombie_params

Затем вам нужно будет определить, какой метод должен вызываться перед каким действием, изменив ваш before_filter так, как в вашем случае:

 before_filter :get_zombie_by_id, :only => :show
 before_filter :get_all_zombies, :only => :index

Таким образом, Zombie.find(params[:id]) будет вызываться только во время действия show. Вы также можете использовать :except, чтобы сделать обратное.

person Geoffrey H    schedule 24.10.2012

это работает, потому что вам нужно отправить обратно (в индексное представление) список ваших зомби. get_zombie_params() выполняется правильно, но не отправляет @zombies в действие index().

вам нужно сделать:

def index 
   @zombies = Zombie.all
   #... the rest of the code
end
person hkairi    schedule 23.10.2012