в обход before_filter, но только при доступе из другого контроллера / представления - PullRequest
0 голосов
/ 26 октября 2011

Я запускаю before_filter для некоторых действий, чтобы проверить, является ли пользователь current_user.

before_filter :correct_user,  :only => [:edit, :update, :destroy]

def update
  @user = User.find(params[:id])
  if @user.update_attributes(params[:user])
    redirect_to current_user, :notice => "User updated!"
  else
    redirect_to current_user, :notice => "User not updated. waa waa."
  end
end

private
def correct_user
  if current_user != @user        
    redirect_to root_url, :notice => "Cannot act on different user."
  end
end

Не уверен, что это лучший способ сделать что-то, но он работает (может, лучше просто использовать current_user вместо поиска @user через params?)

Теперь у пользователя есть много фотографий, и в индексном списке моих фотографий я перечисляю все фотографии пользователя и позволяю ему установить любую фотографию в качестве фотографии профиля. В пользовательской таблице есть столбец primary_photo_id для хранения этого идентификатора, и я использую link_to для установки этого:

=link_to "Make this your profile photo", user_path(@user, :user => {:primary_photo_id  => "#{photo.id}"}), :method => :put

Проблема в том, что before_filter запускается и мешает этому работать, потому что @user, который получается через params [: id], терпит неудачу, потому что это неправильные параметры. Если я удаляю before_filter, он работает нормально, но больше не проверяет правильность пользователя.

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

=link_to "Make this your profile photo", user_path(@user, :primary_photo_id  => "#{photo.id}"), :method => :put

нет.

Спасибо. Я довольно новичок в рельсах и программировании, поэтому все, что вы можете сказать относительно моего конкретного вопроса, и любые плохие практики, которые я делаю с кодом здесь, очень ценится.

1 Ответ

2 голосов
/ 26 октября 2011

Фильтр before (#correct_user) запускается до #update, поэтому ваша переменная экземпляра @user еще не установлена, когда вы сравниваете ее в фильтре, если вы не установили ее в другом до фильтра first. Ваша последовательность выполнения выглядит так:

  1. run #correct_user - сравнить current_user с @user (если не установлено, это ноль). они будут совпадать только в том случае, если пользователь не вошел в систему. Я предполагаю
  2. при условии, что мы справились, запустите #update и найдите @user

Вероятно, самый простой способ решить вашу проблему - просто переместить поиск @user в фильтр before:

before_filter :correct_user,  :only => [:edit, :update, :destroy]

def edit
  # .. as before, but no need to look up user first
end

def update
  if @user.update_attributes(params[:user])
    redirect_to current_user, :notice => "User updated!"
  else
    redirect_to current_user, :notice => "User not updated. waa waa."
  end
end

def destroy
  # .. as before, but no need to look up user first
end

private

def correct_user
  @user = User.find(params[:id])
  if current_user != @user        
    redirect_to root_url, :notice => "Cannot act on different user."
  end
end

Поскольку @user теперь находится в фильтре, нет необходимости искать его снова в каждом из ваших действий контроллера. Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...