My User model looks like this. User has many attached Resume.
class User < ApplicationRecord
has_many_attached :resumes, dependent: :destroy
end
Now in different form, I want to show list of resumes upload by user in descending order. I manage to do that by using following code.
<%= f.select :resume, options_for_select(#user.resumes.includes(:blob).references(:blob).pluck(:filename, :created_at).reverse.map{ |e| e.join(' - ') }), prompt: '-- Select --', class: 'form-control' %>
So now in my select drop down I am able to see all the uploaded resume in descending order. My dropdown looks like this file_name.pdf - 2021-11-30 03-59-59 UTC. I don't want to show time in dropdown. I just want to format it and show date with filename, something like this john_resume.pdf 11/11/2021.
So my question is how can I format the date when using pluck ?
<% options = #user.resumes.includes(:blob).references(:blob).pluck(:filename, :created_at).reverse.map { |e| filename = e.first; created_at = e.last; [filename, created_at.strftime('%d/%m/%Y')].join(' - ') }%>
<%= f.select :resume, options_for_select(options), prompt: '-- Select --', class: 'form-control' %>
Related
I am returning to rails and hobby programming after several years away. I started a new project and I have run into an issue using drop down menus. I am positive it is a small mistake but I am having trouble finding an answer online.
I am making a database of Restaurants. I have a model setup called "meals" which has seeded data for breakfast, lunch, dinner. When creating a new restaurant entry, I want to be able to select from a drop down which meal category the restaurant serves which then saves the meal_id to the restaurant entry. I have meal belongs_to restaurant and restaurant has_one meal. I copied and pasted the below code into the restaurant's form.html.erb and after it didn't work I found more examples online and I do believe it should have worked but it keeps showing that it never saved that data.
<div
class="field">
<%= form.label "Meal" %>
<%= form.collection_select(:meal_id, Meal.all, :id, :meal, { :prompt => 'Select a Meal', :selected => #restaurant.meal_id }, { class: 'form-control' }) %>
Thanks for the help!
One issue:
This is the method, note the order of the variables:
collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
So try this (if Restaurant is the object of the form):
form.collection_select(:restaurant, :meal_id, Meal.all.select(:name), :id, :name, { :prompt => 'Select a Meal' }, { class: 'form-control' })
Your real issue could be elsewhere, but without being able to see the whole form ERB or the controller code, I can only troubleshoot what I see.
project has one_to_many association with stages and financial
stage has one_to_many association with task
task has one_to_many association with sub_task.
In Financial#form view i am trying to pass id to collection_select as an array of combined ids like (eg:-id of stage, id of parent stage . id of task, id of stage.id of task. id of sub_task . id of sub_task)
Also drop-down first accesses all stages then task in current scenario is how can i turn drop-down like first stages then their corresponding all task followed by all sub_tasks?
How can code identify which value is from which table, because drop-down comes from multiple table based on reference
form.html.erb (Finacial)
<div class="field column large-8">
<br>
<%= form.label :acitivity_Select %>
<%= form.collection_select :cost_head, #project.stages.all+ #project.tasks.all+ #project.sub_tasks.all, :id, :task_name, prompt: true %>
</div>
project.rb
has_many :stages
has_many :tasks, through: :stages
has_many :sub_tasks, through: :tasks
So here's how I'd go about solving this:
From a data perspective, there's no need to fetch and render the stages and tasks at all, because you can access that data via the sub tasks. So if you render the select accordingly and store the sub task's ID in the database, you'll be able to access the task and stage from it:
<%= form.collection_select :cost_head, #project.sub_tasks, :id, :task_name, prompt: true %>
Anywhere else:
financial.cost_head.task # => the task
financial.cost_head.task.stage # => the stage
If you want to include IDs in the select for easier selection, you can write your own label_method, e.g. like so:
In the SubTask model:
def full_task_name
"#{task.stage.id}.#{task.id}.#{id} #{task_name}"
end
And then in the form:
<%= form.collection_select :cost_head, #project.sub_tasks, :id, :full_task_name, prompt: true %>
If the sorting is off, you might need to do something like this:
In the controller:
#cost_heads = #project.sub_tasks.includes(task: :stage).order("stages.id ASC, tasks.id ASC, sub_tasks.id ASC")
In the form:
<%= form.collection_select :cost_head, #cost_heads, :id, :full_task_name, prompt: true %>
I have a form_categories table which has a column called active which is of type tinyint/boolean. If the form category record's active attribute is true, then it is active. If false, then it is inactive.
I have a select box that displays all of the records within the form_categories table. I want to style the inactive form_category options red in order to convey to the user that that form_category is inactive. Or Even better, I'd like to put in parentheses next to each inactive form_category option: (inactive) in red letters.
Is this possible?
Below is my select box:
<%= form_tag some_path, method: :get do %>
<%= label_tag "Choose Category" %><br>
<%= select_tag :category_id, options_from_collection_for_select(FormCategory.all, :id, :name), include_blank: true %>
<% end %>
You can use options_for_select and provide the options hash yourself:
options_for_select(form_categories_options, 1) # Where 1 is the current selected option; you would use some value passed from the controller for it
For form_categories_options, you can use a helper, like:
def form_categories_options
FormCategory.all.map do |form_category|
if form_category.inactive
["#{form_category.name} (inactive)", form_category.id]
else
[form_category.name, form_category.id]
end
end
end
If you really want to use options_from_collection_for_select, you can tweak the third argument, namely the text_method: you can define a formatted_name method in your FormCategory model:
class FormCategory < ActiveRecord::Base
...
def formatted_name
if inactive
"#{name} (inactive)"
else
name
end
end
...
end
then use it:
options_from_collection_for_select(FormCategory.all, :id, :formatted_name)
I'm new to Rails and am fixing a Rails 2 site. I have a form that lets the user add information for the starting location (:start) EITHER with an input OR with a dropdown field. However, I have found that when I include both options, only the dropdown (which comes last) submits data, while the input is ignored. What's the right way to include both options?
MY VIEW
<% form_for #newsavedmap, :html=>{:id=>'createaMap'} do |f| %>
<%= f.error_messages %>
<p>Enter a street address, city, and state:
<%= f.text_field :start, {:id=>"startinput", :size=>50}%></p>
<p>Or, select a location from the list:
<%= f.select :start, options_for_select(#itinerary.locations), {:include_blank => true }, {:id=>"startdrop"} %>
<input type="submit" id="savethismap" value="Save Map">
<% end %>
One way to achieve this is by using virtual attributes. Since both fields map to same attribute, you are going to have to pick which one to use.
# app/models/newsavedmap.rb
class Newsavedmap < ActiveRecord::Base
...
attr_accessible :start_text, :start_select
...
def start_text=(value)
#start_text = value if value
prepare_start
end
def start_select=(value)
#start_select = value if value
prepare_start
end
# start_text will fall back to self.start if #start_text is not set
def start_text
#start_text || self.start
end
# start_select will fall back to self.start if #start_select is not set
def start_select
#start_select || self.start
end
private
def prepare_start
# Pick one of the following or use however you see fit.
self.start = start_text if start_text
self.start = start_select if start_select
end
end
Then your form needs to use the virtual attributes:
<%= f.text_field :start_text, {:id=>"startinput", :size=>50}%></p>
<p>Or, select a location from the list:
<%= f.select :start_select, options_for_select(#itinerary.locations), {:include_blank => true }, {:id=>"startdrop"} %>
Other options are:
Use text_field as the primary and update it's value with selected option if user selects an option.
Add a hidden field in your form and use JavaScript to update the hidden field's value when text_field text gets updated or select option changes
With the code I have below in the select field I have all the public_campaigns:
<%= f.select :campaign_id, #public_campaigns.map{|x| [x.name,x.id]} %>
public_campaigns is defined in controller with:
#public_campaigns = #logged_in_user.campaigns.order('created_at desc')
In the form I select the campaign and fill up the rest of the form and at the submit action an invitation is created with campaign_id taken from the campaign I selected in the form, it can be anything from 1 to n
What I need now is to have a default item in select field that will have the value of 0 and named "No campaign", it means I invite someone to a campaign that I have not created yet and in invitation the campaign_id field will be 0.
Thank you for your time.
Do you really need 0? I think use of {:include_blank => "No campaign"} should be enough?
Try this:
<%= f.select :campaign_id, (#public_campaigns.map{|x| [x.name,x.id]} << ["No campaign",0]), {:selected => 0} %>
Well, the fastest way you can do this is something like this:
#public_campaigns = #logged_in_user.campaigns.order('created_at desc')
no_campaign = Campaign.new(:id => '0', :name => 'No Campaign')
#public_campaigns.unshift(no_campaign)
I'm not sure why you are unable to do it this way:
<%= f.collection_select :campaign_id, #public_campaigns, :id, :name, prompt: 'No campaign' %>
Just check if campaign_id.nil? instead of assigning any value to campaign_id