Rails collection_select vs f.collection_select
When you use f.some_form_helper
the helper will already know the name of the model you want to make the field name for. This way you can drop that :post
argument. form_for(@post)
gives you the f
form builder object that knows what model the form is for.
With the regular collection_select
(or any other helper with f.
) you have to pass in, as the first argument, the name of the model the field is for.
Your example is a bit off because you passed in the same arguments to both. f.collection_select
doesn't need the :post
.
This is correct use of the non f.
helper:
<%= collection_select(:post, :author_id, Author.all, :id, :name_with_initial, prompt: true) %>
This is a corrected way to use the f.
helper:
<%= f.collection_select(:author_id, Author.all, :id, :name_with_initial, prompt: true) %>
the f
object has a reference back to the model you passed in to form_for
via f.object
. This is how it knows to call collection_select(:post, ...)
under the hood.
rails - collection_select selected value if defined?
ok I guess I'll feel stupid in 2 mins, but what about
<%= f.collection_select :role_id, roles, :id, :name, prompt: true, @permission.role_id ? {} : {selected: 2 } %>
The reason why your solution is not working is that your if
can return nil
, therefor looking something like that:
<%= f.collection_select :role_id, roles, :id, :name, :prompt => true, {nil} %>
Where {nil}
is syntax error
Can someone explain collection_select to me in clear, simple terms?
collection_select(
:post, # field namespace
:author_id, # field name
# result of these two params will be: <select name="post[author_id]">...
# then you should specify some collection or array of rows.
# It can be Author.where(..).order(..) or something like that.
# In your example it is:
Author.all,
# then you should specify methods for generating options
:id, # this is name of method that will be called for every row, result will be set as key
:name_with_initial, # this is name of method that will be called for every row, result will be set as value
# as a result, every option will be generated by the following rule:
# <option value=#{author.id}>#{author.name_with_initial}</option>
# 'author' is an element in the collection or array
:prompt => true # then you can specify some params. You can find them in the docs.
)
Or your example can be represented as the following code:
<select name="post[author_id]">
<% Author.all.each do |author| %>
<option value="<%= author.id %>"><%= author.name_with_initial %></option>
<% end %>
</select>
This isn't documented in the FormBuilder
, but in the FormOptionsHelper
rails 5 collection select
class Document < ApplicationRecord
has_many :entries
end
class Entry < ApplicationRecord
belongs_to :document
end
In your view file like: new.html.erb
<%= f.select :document_id, Document.all.collect { |p| p.id }, include_blank: true %>
Using collection_select or select or select_tag
Must it be a params value that sets 'selected' in your case? The 'selected' value for collection_select is based on the value of @course.id -- you could make sure that @course represents the one that should be selected.
As for the name, I would stick with the Rails default even when writing your own HTML. It's what dictates how the parameters come into your action. If your elements have names course[id], course[name], course[type], etc., the params would be
{ :course => { :id => xx, :name => xx, :type => xx } }
which is convenient because then you can call
Course.new(params[:course])
Also, you do not need to close your forms with your own HTML form tag. The method form_tag takes a block:
<%= form_tag('/posts') do -%>
<div><%= submit_tag 'Save' %></div>
<% end -%>
And finally... I've used select_tag and built up an options list before. It can get ugly but you could build it in methods in the view helper where it doesn't clutter up your rhtml and where it can be unit tested.
Rails where or select for query chaining
where
is much better from a performance standpoint. where
modifies the SQL so that the DB does the "heavy lifting" of identifying records to retrieve.
select
retrieves all records that meet the initial where
condition, converts them into an array, and uses `Array#select' so the selection is happening at the rails end and you've retrieved more records from the db than you needed and done more processing than is necessary.
Select does have an advantage in that you can select based on model methods that may not be simply extracted from table columns. For example you may have a model method #bad_credit?
which is determined by, say, a credit limit, age if outstanding invoices, and type of account.
Difference between two f.select option
The Codeglot's answer should have been:
<%= f.collection_select :category_id, Category.all, :id , :name %>
(See Rails: undefined method `map' for Ingredient for explanation)
Rails collection_select not getting an id
I see two issues in the code. You already noticed that the category_id
is nil
on the object.
Looking at the form the collection_select
helper sets a category_ids
, but your model's attribute is named category_ids
. Just remove the plural s
<%= f.collection_select(:category_id, Category.all, :id, :name,
# ... %>
The other issue is the configuration of the StrongParameters
in the controller. Strong params methods are working on the params hash and do not know that a category
association exists and that this association works with a category_id
. Therefore your need to be precise and add category_id
to the list:
def create
@item = Item.new(params.require(:item).permit(:name, :description, :category_id))
render plain: @item.inspect
# @item.save
# redirect_to my_page_path
end
Related Topics
Rails Development Server Is Slow and Takes a Long Time to Load a Simple Page
How to Fire and Forget a Subprocess
Best Way to Combine Fragment and Object Caching for Memcached and Rails
Multiple Robots.Txt for Subdomains in Rails
Adding a Method to Built-In Class in Rails App
Check Ruby Http Response for Success
Ruby on Rails and JSON Parser from Url
Converting an Empty String into Nil in Ruby
Error When Starting Rails Server: Warning: Insecure World Writable Dir /Usr in Path, Mode 040777
Best Place to Store Model Specific Constants in Rails 3.1
Carrierwave Crop Specific Version
Run Ruby Script in the Background
Converting an Array of Keys and an Array of Values into a Hash in Ruby
Why Are Constants from Extended Module Not Available in Class Methods Declared with Self