Ruby on Rails Joining Two Strings in Dropdown Text - ruby-on-rails

I have a ruby on rails site with a page called "meetings". These meetings currently work fine, but I want to change the way that one of the drop downs displays its data. Currently, I have this in my controller/view:
Controller
#meeting_times = MeetingTime.select("id, meeting_type, meeting_at").where("
(meeting_at > ?)", Time.now + 1.week).order("meeting_at")
View
<%= f.select :meeting_time_id, options_from_collection_for_select
(#meeting_times, "id", "meeting_at") %>
Currently, as you can see, the dropdown just shows the meeting time. What I want to do make the dropdown show the meeting_type + meeting_time in one string. This sounds easy, however meeting_type is an int value. So, I would need to say "If meeting_type == 0 then display 'Staff Meeting' + meeting_time", and so on. How can I accomplish this without changing the database values for meeting_type?

in MeetingTime model create method
def meeting_time_display
"#{meeting_type_names[meeting_type]} #{meeting_at}"
end
private
def meeting_type_names
##m_type_names ||= ['Staff Meeting', 'Type 2', ..., 'Type n']
end
In view call
<%= f.select :meeting_time_id, options_from_collection_for_select (#meeting_times, "id", "meeting_time_display") %>

Related

toggle between "active" and "inactive" records in an index view

I am extremely "green" when t comes to Ruby & Rails, I could do this easily in VB, but I want to learn rails....
I have a simple index view which shows all the clients in my database, and I figured out how to replace the index action in the controller to display only the clients who are marked as "active" (a field in the clients table), but my head is swimming trying to figure out routing and/or control actions for switching between the two or three recordsets (in VB terms).
My ultimate goal would be to have radio buttons on the index view where the user chooses between "active", "inactive" or "all".
Currently I have this in the clients controller...
#clients = Client.find(:all, :conditions => { :active => true })
##clients = Client.find(:all, :conditions => { :active => false })
##clients = Client.all.order(sort_column + ' ' + sort_direction)
If I comment out two of the lines, the remaining one does exactly as I want.
4 specific questions: (1) How do I write a conditional statement to make this switching occur, (2) WHERE should this be implemented, controller? Routing? Elsewhere?, (3) can this be implemented with user selectable radio buttons in the index view?, and (4) how do I add my "order" condition back in. (I tried just daisy-chaining it onto the end, but that doesn't work.)
Thanks in advance,
MDS
You've got a couple of strategies.
1) Load all the records onto the page, give them a class based on their active status, and hide some of them. The radio buttons have javascript attached, which shows or hides records with a particular class.
2) Load one set of records, and make the radio buttons trigger a request to the server to reload the contents of the list, passing through different params, eg "active=true" or "active=false" (when params[:active] isn't present you could load all of them). It's nicer if this is done via ajax but you could have it reload the whole page.
I wouldn't do this via routing since it's just a params thing.
You can have a dropdown in your index view that has all 3 statuses (radio buttons probably aren't that different but I don't have an example right now):
<%= form_tag("/clients", method: "get") do %>
<%= select_tag(:active, options_for_select([['Active', true], ['Inactive', false], ['All', '']], params[:active]), :prompt => 'Status') %>
<%= submit_tag("Search") %>
<% end %>
(Assuming your controller index page is at /clients, if not change the value in the form_tag)
You then add a scope to your Client model that takes an argument, this way you're not cluttering up your controller:
scope :active, lambda { |active| where(:active => active)}
In your controller, you then call the scope with the param value if it's set:
#clients = Client.all.order(sort_column + ' ' + sort_direction)
#clients = #clients.active(params[:active]) unless params[:active].blank?
No need to mess with routing since you're just passing a params value.

Simple rails filters

I have simplest rails app, with scaffold Tent
here my controller#index for
def index
#tents = Tent
#tents = #tents.where(:brand => params[:brand]) if params[:brand]
#tents = #tents.where(:season => params[:season]) if params[:season]
end
view also standart, generated by scaffold
and here search witch should filter data
= form_tag tents_path, method: :get do
= label_tag "manufacturer"
= select_tag :brand, options_for_select(...), include_blank: true
= label_tag "seasons"
- Tent.pluck(:season).each do |season|
=check_box_tag 'season', season
=h season
= submit_tag 'Submit'
Problem 1:
When i submit from, and params are unselected(select or checl_boxes) i don't want to send this params but they are sent with empty
GET /tents?utf8=...&brand=&season=&commit=Submit
Problem 2:
When i check multiple checkboxes get request is somthing like
GET /tents?utf8=...&brand=Brand&season=4&season=3&commit=Submit
after this i expect that data will be selected for both values, but controller expected that both values is in the field, and returns zero results
any suggestuions?
UPDATE
probably my question solved in railscasts-111 (advanced search form)
About problem 2:
You need to specify season checkbox like below:
=check_box_tag 'season[]', season
But i didnt test it
Problem 2:
You need to write javascript wrapper for form to serialize and send data on submit

Searching multiple fields with Ransack

I'm using Ransack to allow advanced searching on my users. Currently, the users have first_name, middle_name, and last_name columns. Here is my code:
.field
= f.attribute_fields do |a|
= a.attribute_select
...
How can I have a custom one called 'Name', that lets the user search through all three of the columns mentioned above?
Note
I would still like to keep the remaining attributes as options as well, such as email, phone number, etc. Please keep this in mind when determining an answer.
I would suggest to provide a dedicated column for this search. While that might create redundant data, it is way easier to search than doing some SQL magic on the existing columns.
You can easily automate the setting of this field:
before_save :set_full_name
def set_full_name
self.full_name = [first_name, middle_name, last_name].reject(&:blank?).join(" ")
end
Then you can use the normal ransack methods to search this field.
Use this to search multiple fields:
= f.text_field(: first_name_or_middle_name_or_last_name_cont)
This will generate a query like this:
where first_name like '%q%' or middle_name like '%q%' or last_name like'%q%'
when you fill in a q as search parameter
Another approach is to search every attribute of the model, excluding only the fields that you don't want to search. To do this, you could create a custom helper method that builds the label and search field name expected by Ransack's search method. The following method (located in a helper) returns a concatenation of all attributes that you wish to search in a way that Ransack expects:
def most_attributes_cont
most_attributes = []
attributes_to_exclude = [
"id",
"created_at",
"updated_at"
]
ModelName.column_names.each do |column_name|
most_attributes << column_name unless column_name.in?(attributes_to_exclude)
end
most_attributes.join("_or_") + "_cont"
end
Then, just add the method call to your search form:
<%= search_form_for #q do |f| %>
<%= f.label most_attributes_cont %>
<%= f.search_field most_attributes_cont %>
<%= f.submit %>
<% end %>

Array as Parameter from Rails Select Helper

I'm working on a legacy project that is using acts_as_taggable_on which expects tags to come in arrays. I have a select box allowing users to select a tag on a Course in a field called categories. The only way mass assignment create will work is if params looks like this params = {:course => {:categories => ['Presentation']}}. I've currently a view with this helper:
<%= f.select 'categories', ['Presentation' , 'Round Table' , 'Demo', 'Hands-on'] %>
Which will give me a parameter like params = {:course => {:categories => 'Presentation'}}. This doesn't work since Acts as tag gable apparently can't handle being passed anything other than a collection.
I've tried changing categories to categories[] but then I get this error:
undefined method `categories[]' for #<Course:0x007f9d95c5b810>
Does anyone know the correct way to format my select tag to return an array to the controller? I'm using Rails 3.2.3
I didn't work with acts_as_taggable_on, but maybe this simple hack will be suitable for you? You should put it before mass-assignment.
category = params[:course][:categories]
params[:course][:categories] = [category]
If you are only going to allow the selection of ONE tag, you could do:
<%= f.select 'categories', [['Presentation'] , ['Round Table'] , ['Demo'], ['Hands-on']] %>
Each one item array will have first for the display value, and last for the return value, which in this case will both return the same thing, as the first element of the array is the same as the last element when the array as one element.
Seems like select doesn't give you that option.
If I understand correctly, one option might be to use a select_tag instead and just be explicit about where you want the selection in the params:
<%= select_tag 'course[categories][]', options_for_select(['Presentation' , 'Round Table' , 'Demo', 'Hands-on']) %>
That ought to get your params the way you need them.
Here's what I'm using for one of my projects:
<% options = { include_blank: true } %>
<% html_options = { required: true, name: "#{f.object_name}[#{resource.id}][days][]" } %>
<%= f.select :days, DAYS, options, html_options %>
Without html_options[:name], Rails handles the name of the select tag and spits out something like
service[service_add_ons_attributes][11][days]
but I need
service[service_add_ons_attributes][11][days][]
So I override it.
Hope that helps.

Rails select helper - set default?

Rails 2.3.11
I did read this answer, but it's not working for me.
I would like the default option for this selection box to be the event_id passed through the URL.
f.select :event_id, #events, :selected => url_args["event_id"]
An example #events is[["SC 2 Tournament", 195], ["Obstacle Course", 196], ["Mortal Combat", 197]]
The following also didn't work:
adding ".to_i" to "url_args["event_id"
using options_for_select(#events, url_args["event_id"]
Thank you!
This is a lot easier if you use the collection_select helper:
f.collection_select :event_id, #events, :id, :name
Then to select the default option (and have that be selected on pageload), you can simply assign it to whatever Object it is that the form is for within the controller. eg like this:
def new
#events = Event.all
#thing = Thing.new(:event => #events.first)
end
I'm not sure where your url_args comes from, but I'm guessing it's probably from a param in the URL, in which case you can do this:
Thing.new(:event_id => params[:event_id])
One last thing - collection_select won't quite work with #events as you've specified it, as you're using a nested Array, when it's expecting an Array of Objects that it can call id and name on in order to retrieve the values and display text for the select options. To fix that, simply redefine #events within your controller, using one of the ActiveRecord finders, such as Event.all or Event.find(..).
Make sense?

Resources