Как ограничить редактирование конкретными пользователями, создавшими публикацию в ruby on rails?

#ruby-on-rails #ruby #edit #settings

#ruby-on-rails #ruby #Редактировать #Настройки

Вопрос:

Я создал функцию публикации сообщений с использованием ruby. Проблема, с которой я столкнулся сейчас, заключается в том, что функция редактирования сообщения доступна, но она доступна любому отдельному пользователю, независимо от того, кто опубликовал исходное сообщение. Как я могу сделать так, чтобы «ссылка» для редактирования была доступна только для просмотра оригинальным постером. Если требуется какой-либо код, пожалуйста, спрашивайте, спасибо.

Это ошибка, которую я получаю сейчас:

 undefined local variable or method `current_user' for #<ActionView::Base:0x4cdbb48>
Extracted source (around line #7):

4:     <dd>
5:     <%= car.name %><br />
6:     <%= car.description %><br />
7:     <%= link_to('edit', edit_post_path(@car)) if current_user.cars.include?(@car) %>
8:     <%= link_to "Delete", 
9:     :controller => :car, 
10:    :action => :delete,
  

Ответ №1:

Если у вас есть способ получить доступ к объекту user, у вас должны быть отношения к вашим публикациям, подобные этому:

 class User < ActiveRecord::Base
  has_many :posts
end

class Post < ActiveRecord::Base
  belongs_to :user
end
  

Это позволяет вам получать и создавать публикации, ограниченные для пользователя, вот так:

 User.find(1).posts #=> [<Post id:1>, <Post id:2>, <Post id:4>]
  

Enumerable#detect может выполнять цикл по массиву и возвращать первый элемент, значение которого равно true в блоке, например, так:

 @post = User.find(1).posts.detect do |post|
  post.id == 4
end
@post #=> <Post id:4>
  

В большинстве приложений Rails есть какой-то помощник для доступа к текущему авторизованному пользователю. Если нет, я предлагаю вам поместить его в application_controller следующим образом:

 def current_user
  @current_user ||= User.find(whatever_you_do_to_get_the_logged_in_user)
end
  

Примените действия «Найти в редактировании» и «Обновить» к публикациям, принадлежащим пользователю, следующим образом:

 def edit
  @post = current_user.posts.detect{|p| p.id == params[:id] }
end
  

и на ваш взгляд:

 <%= link_to('edit', edit_post_path(@post)) if current_user.posts.include?(@post) %>
  

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

1. Я собираюсь попробовать это сейчас и посмотреть, что получится @unixmonkey

2. что такое p и p.id ? также мой пост называется ‘car’ разве мне не нужно определять идентификатор пользователя для каждого ‘car’, который публикуется? @unixmonkey

3. Я добавил строку кода и т.д. Должен ли я изменить p.id для car.id потому что у меня есть это в качестве идентификатора для каждой отдельной записи, а также как я буду определять переменную current_user в моем car_controller.rb? Пожалуйста, просмотрите ошибку, которую я сейчас получаю в OP

4. p — это временная переменная для проверки каждой записи. когда блок, переданный для выбора, примет значение true, тогда @post будет записью с тем же идентификатором, что и params[:id]. current_user — это своего рода стандарт де-факто в приложениях rails, прошедших проверку подлинности, если вы используете restful_authentication, authlogic или devise. Также предполагается, что у вас есть отношение пользователей к публикациям. Немного отредактирую для расширения.

Ответ №2:

Вам нужно связать запись с создающим пользователем в вашей модели и проверить право собственности и / или разрешение в действии редактирования.

Возможно, было бы неплохо использовать драгоценный камень cancan для обработки разрешений и посмотреть на этот railscast, как использовать его для создания защиты, очень похожей на вашу потребность.

Railscast использует cancan с authlogic, но он может работать и с другой аутентификацией.

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

1. Я не могу использовать внешние дополнения rails и т.д. При создании этого онлайн-приложения, оно должно запускаться на стандартных rails без надстроек

2. Затем посмотрите на код, поймите его и используйте как образец того, как сделать это самостоятельно.