I have a Ruby on Rails application with some generated scaffold.
Now, in one of them I need to add a parameter that wasn't planned initially.
The situation is that I have two objects: Block and Keywords. The relationship between them is has_and_belongs_to_many. That allows me to have many keywords associated to many blocks and vice versa.
I want to add the option to add some keywords to the object Block during the creation.
I added the following code in the /views/blocks/_form.html.erb file:
<div class="field">
<%= f.label :keywords %><br>
<%= f.collection_select(:keywords, #keywords.order(:name), :id, :name, {include_blank: true}, {:multiple => true}) %>
</div>
I added the parameter in the controller as well:
def block_params
params.require(:block).permit(:name, :title, :description, :price, :instagram, :image, :main, :action, :keywords, :block_type_id, :module_keyword_id, :playlist_id)
end
Nevertheless I get this message in the log
Unpermitted parameter: keywords
and the keywords are not added to the block.
What am I missing?
When a parameter is an array, you have to permit it as an array with this:
def block_params
params.require(:block).permit(:name, :title, :description, :price, :instagram, :image, :main, :action, :block_type_id, :module_keyword_id, :playlist_id, :keywords, keywords: [])
end
note the "keywords: []", also note that I also left the ":keywords" key, that permits the param when you send an empty value too (en case you are removing all keywords for example).
Related
I'm sorry this question might seem silly to advanced but here goes
I am trying to set the Piano type in my form to select the preselected value from the database. It currently brings up the first value instead of the preselected value, this is my form entry for the Piano:
<div class="field">
<%= form.label :Type %><br>
<%= form.select(:Type, options_for_select([['Grand', 'Grand'], ['Upright', 'Upright'], ['Console', 'Console'], ['Spinet', 'Spinet']])) %>
</div>
I have tried adding :selected => Tuning.Type to the form to preselect the entry but it doesn't seem to work.
<div class="field">
<%= form.label :Type %><br>
<%= form.select(:Type, options_for_select([['Grand', 'Grand'], ['Upright', 'Upright'], ['Console', 'Console'], ['Spinet', 'Spinet'], :selected => Tuning.Type])) %>
</div>
I'm a little confused as to whether the select box entries are supposed to be entered in my model or not as this is all new to me and I need help moving forward.
My model reads something like:
class Tuning < ApplicationRecord
validates :Client, presence: true
validates :Tel, presence: true
validates :Address, presence: true
geocoded_by :Address
after_validation :geocode
end
But includes nothing in the way of select values for 'Type', what should I do to show up the preselected type? thank you for your help.
I have model named note.rb as follows:
class Note < ApplicationRecord
belongs_to :user
has_many :tags
accepts_nested_attributes_for :tags
end
And also a model named tag.rb:
class Tag < ApplicationRecord
belongs_to :note
end
The form for new note creation is as follows:
<%= form_with scope: :note, url: notes_path, local: true do |f| %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :description %><br>
<%= f.text_area :description %>
</p>
<%= f.fields_for :tags_attributes do |t| %>
<p>
<%= label_tag(:name, "Add a tag") %><br>
<%= t.text_field :name %>
</p>
<% end %>
<p>
<%= f.submit %>
</p>
<% end %>
<div id= "tag-displayer">
<span id= "tags"></span>
</div>
I am trying create a record for tag with a record of note.
In my notes_controller.rb I have
def create
#note = Note.new(note_params)
#note.user = current_user
if #note.save
redirect_to '/notes'
else
render 'new'
end
end
and :
private
def note_params
params.require(:note).permit(:title, :description, tags_attributes: [:id, :name])
end
Now on form submit I get the following:
TypeError (no implicit conversion of Symbol into Integer):
I get the same error if I use:
params.require(:note).permit(:title, :description, :tags_attributes => [:id, :name])
I get the error:
Unpermitted parameter: :tags_attributes
If I use:
params.require(:note).permit(:title, :description, :tags_attributes => [])
Params for form submit:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"iSsLyOb0ZxZP0rfB4I5yfyrw965zJSLrtkroTUzseY2k4o5DwKpKXlyxN6p99pt4Fwju1RhMZPkbNdv+YVSESQ==", "note"=>{"title"=>"test note with Tag", "description"=>"Test note with tag", "tags_attributes"=>{"name"=>"Rails"}}, "commit"=>"Save Note"}
I am not sure what I'm doing wrong, I've tried all possible solutions available to me.
Using Rails 5 with ruby 2.4.1.
Well, if I look at your params, you actually do have strings. There are several ways to fix that, but the most straightforward way in my opinion is just to permit strings instead of symbols. For tags_attributes, that should be 'tags_attributes' => ..., for the rest I'm not sure if I remember correctly: it's either 'title' or :'title', probably the latter. I think the same goes for 'note' or :'note'. I hope you can just play around a bit and see which one it is. I had the error before, so I'm quite certain that should fix it. I hope I can help! Please let me know which one fixes it, I'm curious to know :)
Well i think you don't need to add id in strong parameters
try this: -
params.require(:note).permit(:title, :description, tags_attributes: [:name])
The immediate issue is that your form is passing:
{..., "tags_attributes"=>{"name"=>"Rails"}}, ...}
When it needs to pass:
{..., "tags_attributes"=>[{"name"=>"Rails"}], ...} # The hash is inside an array.
Or possibly:
{..., "tags_attributes"=>{"any_key_except_id" => {"name"=>"Rails"}}, ...}
I'm pretty sure the TypeError is coming from that issue, probably that at some point it's trying to treat the string "Rails" as a hash and tries to call "Rails"[:id] on it.
My hunch (without reproducing your entire setup) is that this can be solved by changing your line that says:
<%= f.fields_for :tags_attributes do |t| %>
to
<%= f.fields_for :tags do |t| %>
If you look at the documentation for fields_for, it uses the name of the association, without the _attributes at the end. With :tags_attributes, I think the form doesn't know what to do with it, assumes it's a single item instead of a collection, and so doesn't nest the attributes in an array.
Note that if you want to have it display the field for a new tag (instead of just existing tags), I believe you'll have to call #note.tags.build somewhere before the fields_for call so that there's an unsaved Tag entity in the tags collection.
I think it has something to do with your model declaring has_many :tags and your form data coming in as an object :tags_attributes => {id: "", name: ""}.
The TypeError (no implicit conversion of Symbol into Integer): error could be bubbling up when you are trying trying to save the note #note.save or when you are initialising it using #note = Note.new(note_params) but not because of Strong parameters. Strong parameters should permit those parameters because the definition matches the form data you are sending.
Try modifying the frontend to send tags in an array format like :tags_attributes => [{id: "", name: ""}, {id: "", name: ""}]
There is blog that is almost if not exact similar to the problem you are facing, check it out http://billpatrianakos.me/blog/2013/09/29/rails-tricky-error-no-implicit-conversion-from-symbol-to-integer/
I am building a Rails app that tracks musicians. I want each user to be able to to select multiple genres they like from a form when they create a profile. I want to store it within the "profile" table for the user in the "genre" column. Right now, I have this, but it only allows me to select ONE option. I want the dropdown to allow multiple options. Is that possible? I'm sure this is very simple.
<%= simple_form_for #profile do |f| %>
<%= f.input :genre, collection:['Rock','Blues','Jazz','Classical','Soul','R&B','Alternative', 'Other'], label: "Favorite Genres" %>
Right now, genre is a string. Do I need to pass an array? How would I do that?
There are 2 things you need to do to handle a multi-select with rails.
1) Allowing the user to select multiple options on the form with the {:multiple => true} option.
<%= simple_form_for #profile do |f| %>
<%= f.input :genre, collection:['Rock','Blues','Jazz','Classical','Soul','R&B','Alternative', 'Other'], label: "Favorite Genres", input_html: {:multiple => true} %>
2) Let your controller accept an array of params for the value.
def profile_params
params.require(:profile).permit( :years_spent_playing, :user_id, :name, :bio, :age, :city, :state, :primary_instrument, :second_instrument, :third_instrument, :status, :looking_for, :image, :genre => [])
end
Im not sure your setup but I get the feeling you may not have the proper models and associations setup to handle this in the ideal way. I would suggest looking at adding a has_many :through association and breaking your genres out into a separate model and table.
What are the changes to be made in the controllers and the collection for accepting multiple values from a collection select.
The association between the models is:-
product has many categories through product_categories
categories has many products through product_categories
product_categories is the join table.
Below is my collection select, where i am using chosen to select multiple values.
<%= ps.collection_select :product_id, Product.all, :id, :product_name, {prompt: "Select Product"}, {class: "form-control chosen-select",:multiple => true}
Controller params
params[:spare].permit(:id, :name, :desc,:code,:manufacturer_id, :product_ids,{:attachments_attributes => [:id, :attachment, :remote_attachment_url, :_destroy]})
Also tried with nested attributes
params[:spare].permit(:id, :name, :desc,:code,:manufacturer_id,:product_ids,{manufacturer_service_centers_attributes: [:id, :service_center_id, :manufacturer_id, :_destroy]},{:attachments_attributes => [:id, :attachment, :remote_attachment_url, :_destroy]})
What changes should i do here for it to take product_ids? .
I was able to apply chosen multi select, These are the steps i followed.
with chosen select:
<%= f.select :product_ids, Product.all.collect { |u| [u.product_name_code, u.id] }, {}, {:multiple => true, :class => "chosen-select"} %>
Controller
params[:spare].permit(:id,:product_ids => [])
Hope it helps :)
Thanks :)
I have a drop down select that is set up like below:
<%= select_tag :city_id, option_groups_from_collection_for_select(#regions, :cities, :name, :id, :name) %>
It works fine, except that when I load the edit view the list loads the first item in the select, not the saved value. Is there parameter I'm missing? On rails 4.
According to the documentation on option_groups_from_collection_for_select found here: http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/option_groups_from_collection_for_select
It has a sixth parameter that is the selected value, so just add the last parameter with the value you want and it will work:
<%= select_tag :city_id,
option_groups_from_collection_for_select(#regions, :cities, :name, :id, :name, "your_city") %>
Instead of using select_tag use select
# f being your form object
<%= f.select :city, option_groups_from_collection_for_select(#regions, :cities, :name, :id, :name) %>
Considering you have a valid association with city