2016-10-15 14 views
1

У меня есть сообщение, которое имеет получатель, проводным так:Pass массив идентификаторов в качестве одного скрытого поля

class Message < ApplicationRecord 
    has_many :message_recipients 
    has_many :recipients, through: :message_recipients, source: :user 
end 

Я прохожу user_ids как GET паров к новой форме сообщений для предварительной propulate получателей:

def new 
    @message = Message.new 
    @message.recipients = User.where(id: params[:user_ids]) 
end 

создал strong_params так:

def message_params 
    params.require(:message).permit(
    :subject, 
    :body, 
    recipient_ids: [] 
) 
end 

И создал форму следующим образом:

= simple_form_for @message do |f| 
    = f.hidden_field :recipient_ids 

Я ожидал, что все это просто работать, но потом я понял, что в одиночку это скрытое поле не рассматривается как скаляр, так что это игнорируется strong_params (в противном случае я бы делать :recipient_ids вместо recipient_ids: [], но тогда он не будет в конечном итоге, как массив).

Так я думал об этом:

= hidden_field_tag 'message[recipient_ids][]', @message.recipients.pluck(:id) 

Но тогда контроллер будет анализировать Params, как это:

message_params[:recipient_ids] => ["1, 2, 3"] 

вместо:

message_params[:recipient_ids] => ["1", "2", "3"] 

Так что я имел для возврата к уродливому:

- @message.recipient_ids.each do |recipient_id| 
    = hidden_field_tag 'message[recipient_ids][]', recipient_id 

И все это сработало.

Но я чувствую, что это далеко не идеально, потому что теперь у меня есть десятки элементов DOM, лежащих вокруг, а не потенциально только один.

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

Может быть, Rails должен быть немного умным при получении одного скалярного поля чисел, разделенного запятыми?

Ну, что вы, ребята, думаете? версия

Rails: 5.0.0

+0

Я думаю, что вы раскрыли оба пути подойти к этой проблеме в вашем вопросе: 1) с использованием нескольких входов с именем [] в имени, чтобы они обрабатывались как массив или 2) сериализовали данные в одном входе формы, а затем безриализовали его на сервере. Отправка меньшего количества элементов может способствовать первому подходу, в то время как другие элементы могут способствовать последнему подходу. – Puhlze

ответ

0

Держите recipient_ids как простой атрибут в message_params

def message_params 
    params.require(:message).permit(
    :subject, 
    :body, 
    :recipient_ids 
) 
end 

И потом message_params[:recipient_ids].split(",")

Так будет

"1, 2, 3".split(",") 
=> ["1", " 2", " 3"] 
+0

Куда бы вы поместили этот код? Тогда мне пришлось бы думать о том, чтобы называть это как в действиях 'create', так и' update'. Вы видите мою точку зрения, она начинает загромождать контроллер ненужной логикой, не так ли? –

+0

Я бы сделал это в вашей модели.rb. создайте новый сеттер, который принимает значение, разделенное запятыми, и преобразует его в массив и в вашу форму, просто преобразуйте значение в запятую – Kosmonaut

0

yourmodel.Р.Б.

message_params=(val) 
    if val.class==String #if we pass a string 
    super(val.split(',')) #split back into array and assign value 
    else 
    super(val) 
    end 
end 

, а затем в вашей форме строитель (при условии, simpleform)

f.input :message_params, 
    as: :hidden, 
    input_html { 
    value: @yourmodel.message_params.join(',') #split array back into comma separated string 
    } 

и