rails4-autocomplete. Getting association name in autocomplete field - ruby-on-rails

I'm trying to add an auto complete field using https://github.com/peterwillcn/rails4-autocomplete
I have a Topic model that belongs to a City. City belongs to Country. i.e. city = London. then city.country.name = England.
I can get my autocomplete to display the city name with
#controller
class TripsController < ApplicationController
autocomplete :city, :name
#view
<%= f.autocomplete_field :city_id, autocomplete_city_name_trips_path %>
But I want the country name to show in the auto complete field too. i.e. London, England. not just London.
Is there a better way to do this?
EDIT: also this passes the city name to the controller, I would like it to pass the city_id

If you've got the country in another field then it is pretty easy with autocomplete. You want to use the update_elements option in your view to tell autocomplete what other fields need to be filled in.
<%= f.autocomplete_field :city,
autocomplete_department_name_incidents_path,
update_elements: {country: '#trips_country'} %>
The #trips_country in the above snippet is the ID of the field in your form that you want updated. country: is extra data that autocomplete fetches for you.
So you also need to go to your form and tell autocomplete to grab other data.
autocomplete :city, :name, extra_data: [:country]
That's what would work if everything were in the same model. I've never tried to pull data from a different model using autocomplete so I don't know if it will work. Hopefully this is enough of a push to get you there.

The rails4-autocomplete gem has the option display_value which is what you want to use.
class TripsController < ApplicationController
autocomplete :city, :name, display_value: :name_with_country
Then in the City model
def name_with_country
name + ', ' + country.name
end

Related

Adding custom field in rails form helper

I'm working in a rails app and for country state and city select field I want to create a custom field so that It can be used later as already existed field.
For example
f.country_select :country
Above field should automatically generate a select with countries list.
I want three fields country, state and city so connected that when country field selected state select field gets state list and when state is selected city select works same.
Thank you for your valuable answer.
For this you should start from here . In this rails cast you can understand how to dynamically populate data in child(State) select box on basis of parent(Country) selection.
You need to extend functionality for cities same.
But in given tutorial you should have countries and state data. For managing that data you can use City-State.
In tutorial it is used like Country.find(:all), So you need to change it to CS.get. and for state of a selected country like CS.get :us.
Hope this works.
Yes, you can add this method to ActionView::Helpers::FormBuilder class
here is example for
class ActionView::Helpers::FormBuilder
def error_message_on(method, options = {})
#template.error_message_on(#object_name, method, objectify_options(options))
end
end
and then you can do this
= f.label :description, I18n.t(:description)
= f.text_field :description, class: 'form-control'
= f.error_message_on :description
You can use the gem city-state github gem link .

How to set-up Rails form select for a collection

I'm working on a code base that I'm not very familiar with, specifically Haml. I need to set-up a select dropdown to select a user.
I have the following code in my controller:
def edit
#franchise = Franchise.find params[:id]
#ab_reps = User.where role: "admin-ab"
authorize! :update, #franchise
end
I have the following code in my form (that doesn't currently work):
= f.select :ab_rep, options_for_select(#ab_reps, f.object.ab_rep), {prompt: "AB Representative"}, {label: false, right_class: "col-sm-10", class: "ab-rep-field"}
Couple questions:
1.) #ab_reps is an array of user objects. I have the following method in my user model:
def name
[first_name, last_name].compact.join(" ")
end
How do I get the select to display the user names instead of the user objects (which it currently does) ?
2.) Is my current set-up even close to being correct?
Thanks for your help!
You are close, you need to provide the methods for the option value and the option text, as well as the collection which in your case is #ab_reps. Additionally you can provide a hash for prompts and for html_options such as class names, which you've done.
Rails has a few different helpers you can use for select tags including options_from_collection_for_select. I've used collection_select often, http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/collection_select
= f.collection_select :ab_rep, #ab_reps, :id, :name, {prompt: "AB Representative"}

Change default population string for form field

I'm building a form on ROR4, using the simple_form gem, to modify my user's data. The thing is that my database is normalized to have the user's first and last name in lower case. So I have the following in my User model:
before_save :lowercase_names
def lowercase_names
self.first_name.downcase!
self.last_name.downcase!
end
But of course when I populate my upadate form with the user object I get the following:
First name: carlos
Last name: ledezma
I was wondering if there is a way to override this behavior so Rails would print instead:
First name: Carlos
Last name: Ledezma
That is, the titleized version of the fields.
Thanks in advance for the help
In your form set the value to titleized name
=f.input :first_name, :value => #user.first_name.titleize
The above line will vary depending on if you are using simple form or not. But it will give you the basic idea. You are overwriting the value of the input field
If you want it to be changed everywhere, then override getter for first_name and last_name
def last_name
self.read_attribute(:last_name).titleize
end
def first_name
self.read_attribute(:first_name).titleize
end
Be aware that this will titleize your first name and last name everywhere you call the getter
Try using the value attribute of the text_field helper in your form to set the shown value as the capitalized first and last name:
<%= f.input :first_name, :value => f.object.first_name.capitalize %>
<%= f.input :last_name, :value => f.object.last_name.capitalize %>
Updated
Also, you can override getter method in User model like:
def first_name
self.read_attribute(:first_name).capitalize
end
def last_name
self.read_attribute(:last_name).capitalize
end

Cannot retrieve lookup values correctly

I've built a lookup table in my Rails application.
It is a table that stores lookup text values for drop-down pickers or possibly check boxes. I want the lookup table to have a view associated so the values can be easily edited. I also may want to share lookup values among multiple models for a single field in the future.
So far I've managed to get it to work for the selection of values, but then displaying the text value again on a show or index view has been problematic.
This is how I built the lookup table
rails g scaffold Lookup field_name lookup_text table_name note
In the edit.html.erb where there is a lookup on a field, I've got code like this, which works and allows me to pick from a list.
<div class="field">
<%= f.label :status %><br />
<%= f.collection_select :status, Lookup.find(:all,:conditions => ["table_name = 'course' and field_name = 'status'"]), :id, :lookup_text, include_blank: true,:prompt => "Status" %>
</div>
That all works fine. When I try to display it back I cannot find the correct syntax. The best I have found is this:
(in the controller)
#status = Lookup.where(:id => #course.status).pluck(:lookup_text)
(in the view)
<p>
<b>Status:</b>
<%= #status %>
</p>
I think I am getting the entire object. It displays like this:
Status: ["Active"]
My questions are:
(1) How do I display the value only?
(2) Is this the best approach?
I've had a look at these and other SO questions, but none are really what I am looking for:
Rails Polymorphic with Lookup Table
Implementing a lookup table in Rails
EDIT
OK this works, but it doesn't look like it is the correct solution. Has anyone got a better way of doing this?
#status = Lookup.where(:id => #course.status).pluck(:lookup_text)[0]
Just another way to show the value is #status = Lookup.find(#course.status).lookup_text
Why not to try use classes for different lookups:
class CourseStatus < ActiveRecord::Base
set_table_name "lookups"
default_scope where("table_name = 'course' and field_name = 'status'")
end
class Course
belongs_to :course_status
end
You then can use:
CourseStatus.all # e.g. to fill select options
Course.first.course_status.lookup_text # => "Active" or smth else
Or without classes:
class Lookup
def self._by_table_and_field(table, field)
['table_name = ? and field_name = ?', table, field]
end
scope :by_table_and_field, lambda { |table, field|
where(Lookup._by_table_and_field(table, field))
}
end
class Course
belongs_to :status, class_name: 'Lookup', conditions: Lookup._by_table_and_field('course', 'status')
end
Lookup.by_table_and_field('course', 'status').all
Course.first.status.lookup_text

Rails 3: create input field for each element of a collection (MongoID)

I have two models, Item and Bid
class Item
include Mongoid::Document
field :name, type: String
has_many :bids
end
class Bid
include Mongoid::Document
include Mongoid::Timestamps::Created
field :bid, type: Float
field :bidder, type: String
belongs_to :item
end
In views/prices/index I would like to list all items in a table and for each item put a field next it in which people can enter a number. At the bottom of the form should be a submit button for all records.
How is this best achieved?
There's plenty of code out there explaining how to add, for instance, several questions to one survey (http://railscasts.com/episodes/196-nested-model-form-part-1) but I couldn't find an example that shows how to add one new record for each of an existing element of a collection.
I don't think you need to dynamically add a form for each item if you know you are going to use all of the items there to begin with.
Quick and Dirty:
form_for(#items) do |f|
#items.each do |item|
f.label item.name
f.text_field item.name.to_sym, :value => "1"
end
f.submit "Submit"
end
I haven't tried this and that code isn't tested, but I would assume if you do some work in the controller to build each bid it should be fine. Also amount would be a better variable name for the bid class than using Bid.bid.
The proper way to do this (which would also allow updates) would be to make a nested form and then use fields_for method to actually look at a live bid object: http://archives.ryandaigle.com/articles/2009/2/1/what-s-new-in-edge-rails-nested-attributes

Resources