In addition to showing the challenge's name. I also want to show its deadline next to the name.
It would look like this for example:
Visit London 09/09/16
Make $1,000,000 10/15/18
Knit a Scarf 01/11/19
Instead of just this:
<%= f.collection_select :challenge_id, current_user.challenges.order(:deadline),:id,:name, include_blank: true %>
Define a method name_with_deadline in challenge.rb
def name_with_deadline
"#{name} #{deadline}"
end
and then make use of this method as label in the collection.
<%= f.collection_select :challenge_id, current_user.challenges.order(:deadline),:id, :name_with_deadline, include_blank: true %>
The name_with_deadline method will called for every object in the collection to retrieve the label text.
Hope this helps!
You can add a virtual attribute to you model like below:
def name_deadline
"#{name} #{deadline}"
end
collection_select:
<%= f.collection_select :challenge_id, current_user.challenges.order(:deadline),:id,:name_deadline, include_blank: true %>
Related
I have a collection_select in a rails form that looks like this:
<%= form.collection_select :post_id, Post.all, :id, :title, {}, { class: "mt-1 block" } %>
What I can't seem to figure out from the docs or googling, is how to pass multiple attributes from the Post to the dropdown so the user sees more than just the :title. Something like this:
<%= form.collection_select :post_id, Post.all, :id, :title + :category, {}, { class: "mt-1 block" } %>
I can create a custom method to pass to text_method like :title_with_category in the Post model like:
<%= form.collection_select :post_id, Post.all, :id, :title_with_category, {}, { class: "mt-1 block" } %>
Post.rb:
def title_with_category
self.title + " " + self.category
end
But is this the best way to do this? If so, what is the appropriate place to define this? The model? Or should this be in a helper? If it's a helper, should it be in the application helper?
Firstly, it's safer to do this in case one of the items is ever nil:
Post.rb
def title_with_category
"#{title} #{category}"
end
Next your selection. In the controller, return the options as an attribute:
def new
#post_options = Post.all.collect{|post| [post.id, post.title_and_category]}
# OR
#post_options = Post.all.collect{|post| [post.id, "#{post.title} #{post.category}"]}
# you can skip the model method with the second option
end
And on the form:
<%= form.select :post_id, #post_options, {}, { class: "mt-1 block" } %>
See form select.
You can pass a callable to collection_select for both the value_method and text_method arguments:
<%= form.collection_select :post_id,
Post.all,
:id, # value_method
->(p){ "#{p.title} #{p.category}" }, # text_method
{},
{ class: "mt-1 block" }
%>
A callable is any object that responds to the call method such as lamdba and proc objects.
It is called with the post for each iteration of the loop.
What is the appropriate place to define this? The model? Or should this be in a helper? If it's a helper, should it be in the application helper?
There is no clear cut answer if you choose to extract this out into a separate method. The model would be the simplest solution but you can also argue that presentational logic should be separated from buisness logic and that models already have tons of responsiblities.
I think we can all agree on that ApplicationHelper is the least suitible option unless you to just are aiming to toss your code into a junk drawer.
This code could go into Post, PostHelper, PostPresenter (if you're into the decorator pattern) or a custom form builder (which seems slightly overkill).
I am creating a form has a drop down selection. I want to use two "text_method"s for the input but I am unsure how to do this. I want to include the year and name (both are two different columns in my rails model.
Here is what I have but it does not work:
<%= f.collection_select :bat_id, Bat.all, :id, :model_year, :model_name, include_blank: true %>
Here is the official documentation- http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_select
Use this in your view:
<%= f.collection_select :bat_id, Bat.all, :id, :model_year_and_name, include_blank: true %>
Add a method like this to your Bat model:
def model_year_and_name
"#{model_year} #{model_name}"
end
I have a form_for in Rails that uses the collection_check_boxes method for an array of parts that get listed as check boxes. I want the label of the checkbox to be a composite of two methods so that each part's checkbox is labeled with it's name and it's SKU number:
my form code:
<%= collection_check_boxes(:service, :part_ids, #parts_list, :id, :sku, {}, {checked: true}) %>
this works perfectly to create a list of check boxes. But each label is only the :sku since I can only pass it one method for the label. Does anyone know of a way to create a custom label for these? I have read the api docs and it mentions using a do |b| ... end block but doesn't explain how to use it or why.
Here is the modified form code:
<%= collection_check_boxes(:service, :part_ids, #parts_list, :id, :sku, {}, {checked: true}) do |b|
b.label { b.check_box + b.object.name + " " + b.object.sku}
end %>
NOTE:
b.object.name #### Assuming that name is field name in your model
b.object.sku #### Replace with b.object.sku.to_s if sku is numeric field.
You could define a custom field in your model:
def cb_label
"#{name} #{sku}"
end
and in the collection
<%= collection_check_boxes(:service, :part_ids, #parts_list, :id, :cb_label, {}, {checked: true}) %>
How would I create a drop down list which displays the employees name as well as badge number?
At the moment I have:
<%= f.collection_select(:employee_id, Employee.all, :id, :name) %>
And I want to do something like:
<%= f.collection_select(:employee_id, Employee.all, :id, :badge_number + :name) %>
In your Employee model put a method:
def badge_name
"#{badge_number} - #{name}"
end
And use it in your view:
<%= f.collection_select(:employee_id, Employee.all, :id, :badge_name) %>
i'm having a problem to create a text_field without a method association. Maybe i even don't need it :-)
I have two radio_buttons associated to the same method:
<%= radio_button :comment, :author, "anonymous" %> Anonymous <br>
<%= radio_button :comment, :author, "real_name" %> Name <br>
What i would like to do is to have an text_field which when the user click on the radio_button "real_name" i can verify the value in this new text_field.
Basically my Controller would be something like:
#comment = Comment.new(params[:comment])
if #comment.author == "real_name"
#comment.author = "value-from-the-new-textfield
end
There is any way to do it?
Regards,
Victor
If you want to generate a text_field without an associated object/method, use text_field_tag
You can use another parameter instead of :comment
<%= radio_button :verify, :author, "anonymous" %> Anonymous <br>
<%= radio_button :verify, :author, "real_name" %> Name <br>
So in your controller you can get the value of selected button with
if params[:verify][:author] == 'real_name' ...
text_field_tag is definitely the easiest way, but if you want to add a field that acts as part of a model, adding an attr_accessor attribute might be worth looking into as well.