Любой способ поместить скрытое поле в формы для ресурсов с ассоциацией принадлежащим - PullRequest
6 голосов
/ 27 июля 2010

Я изучаю Rails, написав простое приложение для задач TODO.Две модели:

class List < ActiveRecord::Base
  has_many :tasks, :dependent => :destroy
  # ...
end

class Task < ActiveRecord::Base
  belongs_to :list
  # ...
end

Задачи маршрутизируются как вложенные ресурсы в списках.Таким образом, когда пользователь создает новую задачу, сообщение POST отправляется на /lists/:list_id/tasks.Пока что в форме Tasks#new есть

f.hidden_field :list_id, :value => params[:list_id]

, но это ужасное решение, потому что любой может изменить значение этого скрытого поля.

Какое здесь соглашение? Должен ли я поместить что-то вроде

@task.list_id = params[:list_id]

в действие Tasks#create и избавиться от скрытого поля, или, может быть,

@task = List.find(params[:list_id]).tasks.new(params[:task])
if @task.save
  # ...
end

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

Редактировать:
Да, ну, был подобный вопрос , и его ответ в значительной степени покрывает мой вопрос.Если у вас есть другой, пожалуйста, опубликуйте его.

Ответы [ 2 ]

9 голосов
/ 27 июля 2010

Ты прав - это было бы ужасно.Нет необходимости в скрытых полях.Что-то вроде следующего.

В вашем TasksController:

def new
  @list = List.find(params[:list_id])
  @task = @list.tasks.build
end

def create
  @list = List.find(params[:list_id])
  @task = @list.tasks.new(params[:task])

  # etc
end

В вашем Task#new представлении:

<% form_for [@list, @task] ... %>
  ...
<% end %>
0 голосов
/ 12 августа 2017

Если вы беспокоитесь о безопасности (например, если один пользователь создает задачи в списках другого пользователя - и я полагаю, что это так, потому что вы не хотели использовать скрытое поле с указанием anyone can change value of that hidden field), я не будупосмотрите, как решение @bjg лучше вашего, так как вы в любом случае получаете @list из params, и любой может манипулировать параметрами в браузере (изменить URL-адрес для публикации так же просто, как изменить значение скрытого поля).

Один из распространенных способов решения этой проблемы без реализации более сложного решения для разрешения - это просто использовать current_user ассоциации, например:

def new
  @list = current_user.lists.where(id: params[:list_id]).take
  @task = @list.tasks.build
end

def create
  @list = current_user.lists.where(id: params[:list_id]).take
  @task = @list.tasks.new(params[:task])

  # etc
end

Таким образом, независимо от того, что являетсязначение params [: list_id] (оно могло быть изменено пользователем), вы можете быть уверены, что @task попадет в учетную запись этого пользователя, поскольку @list найдет только запись, которая принадлежит current_user.

Вы можете развить это в реальном приложении, вернув сообщение об ошибке, если @list не найден.

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