Confusion with form

Hi, I’m both a Ruby and Rails newbie here.

I am trying to play around with forms and am a bit confused. I have a User controller and there is a string field in the User called “playlists”.

I want to create a multiple select dropdown where my user can select one of the playlists I am providing. How do I do this so that whatever they select/type in is saved in the playlists field?

So for example, I want the user to see here

Playlist 1

Playlist 2

Playlist 3

Submit

And let’s say for example they select Playlist 1 and Playlist 3. How can I store this in the playlists field in the user?

I’m getting really confused because everyone is saying I need to use the “new” method on controllers to use forms and I’m honestly so lost.

If you really want to store this property in the User itself, then your only option will be to serialize it so it can be stored in a text/string property like this. In the User model add this configuration:

serialize :playlists, Array

Now, in your view, you can add a picker (or a set of checkboxes, which would be kinder to the user) for your options:

form.collection_check_boxes :playlists, ['Playlist 1', 'Playlist 2', 'Playlist 3'], :to_s, :to_s

And in your UsersController, make sure that the strong_parameters method is expecting an Array from that property:

def user_params
    params.require(:user).permit(:name, :quest, :favorite_color, playlists: [])
end

That should be all you need to do.

Possible reason why you’re finding this hard to do: it’s not a very scalable or useful coding style, particularly if you ever want anything about it to change. Let’s say you want to change all the playlists, or add to them later. You aren’t saving a reference to a real object, just a string, so there’s no way to know that Playlist 1 stored in User 24 is the same as Moody LoFi in user 4294.

The right way to do this would be to create a separate Playlist model, and then a “join model” like Subscription or Choice, and then use the accepts_nested_attributes_for module to register the user’s preference in a User form.

class User
  has_many :subscriptions
  has_many :playlists, through: :subscriptions
  accepts_nested_attributes_for :subscriptions
  ...
end

class Playlist
  has_many :subscriptions
  has_many :users, through: :subscriptions
end

class Subscription
  belongs_to :user
  belongs_to :playlist
end
# in your view
<%= fields_for :subscriptions do |form| %>
<%= form.collection_check_boxes :subscriptions, Subscription.all, :name, :id %>
<%- end -%>

That may seem like more work initially, and it is, but it pays off later, and is probably a lot faster in large data sets, because the array data type (in a text column) can’t be indexed as efficiently as the numeric indexes that make up a three-way join like I’ve described above.

Hope this helps,

Walter