Rails radio_button check conditionally in loop - ruby-on-rails-4

I have radiobuttons creaated in loop.
- #annual_packages.each do |plan|
= f.radio_button('plan_id', plan.id)
= plan.title
How can I make condition to check radio if plan.id == #plan.id
Doesn't work:
= f.radio_button('plan_id', plan.id, checked: (plan.id == #plan.id))
Loop code:
= form_for #organization, url: subscription_create_path, remote: true, method: :post do |f|
- unless #annual_packages.blank?
- #annual_packages.each do |plan|
= f.radio_button('plan_id', plan.id)
= plan.title

Can you post your form_for code?
Cause if your column plan_id have any value, it should be checked automatically if it matches the tag_value`.
If the current value of method is tag_value the radio button will be
checked.
http://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-radio_button

If you are using simple_form or form_for, and f is your form object then you can simply do:
for form_for:
radio_button(object_name, method, tag_value, options = {}) refer
in your case:
- #annual_packages.each do |plan|
radio_button("your object name", "plan_id", plan.id, options = {})
If the current value of method(object.plan_id) is tag_value(plan) the radio button will be checked.
for simple_form:
= f.input :plan_id, as: :radio_buttons, collection: #annual_packages

Related

Hide empty group in Ag-grid after row update

How to remove empty groups from ag-grid after updateRowData. In the plnkr example, I am modifying country value for the row, I expect group name to be changed but instead a new group is created.
Code for modifying country name:
let toBeUpdate = [];
this.gridApi.forEachNode((rowNode, index) => {
if(rowNode.data && rowNode.data.athlete == 'Sadiq Khoja'){
var data = rowNode.data;
data.country = 'AAA Unknown X';
toBeUpdate.push(data);
}
});
this.gridApi.updateRowData({update:toBeUpdate});
https://plnkr.co/edit/PTuwR5zejS2xiLIg
(Press 'Add' button to change the country name)
UpdateRowData works when there is no row group.
In this case, instead of using updateRowData try using setRowData -
this.gridApi.setRowData(toBeUpdate);
This will also refresh the grid to reflect the changes in the row.
For more information you can read here - https://www.ag-grid.com/documentation/javascript/data-update/
The correct way to update your data would be to use the setDataValue on rowNode (see here).
Once you update your data, you need to refresh your view for grouping via the api by calling refreshClientSideRowModel.
So your update funciton should be as follows:
this.gridApi.forEachNode((rowNode, index) => {
if(rowNode.data && rowNode.data.athlete == 'Sadiq Khoja'){
rowNode.setDataValue('country', 'AAA Unknown X');
}
});
this.gridApi.refreshClientSideRowModel('group');
Demo

How to Combine many similar methods and views into one

I want to combine similar methods and views into one, but still keep the url name, like the following:
Home/recommends/categories/shopping
Home/recommends/categories/nightview
Home/recommends/categories/food
Home/recommends/categories/area
I don't want to use params like "?something=xyz" in url.
In routes.rb:
resources :recommends, only: :index do
collection do
resources :categories, only: :show, controller: 'recommends' do
collection do
get :food
get :area
get :shopping
get :nightview
end
end
end
end
In controllers:
def food
set_paginator
#recommends = UserRecommend.where(category: "food").order('created_at desc').offset(#offset).limit(#limit).all
#number_of_recommends = UserRecommend.where(category: "food").count
end
def area
set_paginator
#recommends = UserRecommend.where(category: "area").order('created_at desc').offset(#offset).limit(#limit).all
#number_of_recommends = UserRecommend.where(category: "area").count
end
...
In views I have:
food.html.slim
area.html.slim
shopping.slim
nightview.slim
Which are using the same code, just different names in h1:
h1
| Shopping ( or Area or Food... )
= " (#{#number_of_recommends})"
= render partial: "layouts/paginator",
locals: { total_items: #number_of_recommends, per_page: #limit, current_page: #page }
= render partial: "table", locals: { recommends: #recommends }
Can anyone help me refactor this code?
You can (and should) have a single route, a single action, and a single view. The key is to make the variable portion of your URL into an actual variable. You do this using dynamic segments.
First, a single route. There is no need to use resources if you're not actually generating multiple RESTful actions:
get "/recommends/categories/:category" => "categories#show"
You can add criteria on what is allowed for the :category segment:
get "/recommends/categories/:category" => "categories#show", category: /food|area|shopping|nightview/
Next, a single action:
class CategoriesController < ApplicationController
before_action :set_paginator
def show
# params[:category] is "food"/"area"/etc
categories = UserRecommend.where(category: params[:category]).order('created_at desc')
#recommends = categories.offset(#offset).limit(#limit)
#number_of_recommends = categories.count
end
end
Finally, a single view:
# app/views/categories/show.slim
h1
= params[:category].capitalize
= " (#{#number_of_recommends})"
= render partial: "layouts/paginator",
locals: { total_items: #number_of_recommends, per_page: #limit, current_page: #page }
= render partial: "table", locals: { recommends: #recommends }
I would consider it better to use localization to turn the params[:category] into a title, which would give you more control, rather than relying on simple capitalization of the URL segment:
# app/views/categories/show.slim
h1
= t params[:category]
And:
# config/locals/en.yml
en:
categories:
show:
food: 'Food'
area: 'Area'
nightview: 'Night View'

Show virtual field in rails view

I have been using the information here (http://ngauthier.com/2013/08/postgis-and-rails-a-simple-approach.html) so that the search results in my app can be shown based on proximity.
I am listing all tasks with their associated project information - a project can have multiple tasks.
I have the following AR query in my Project controller:
#results = Task.select('tasks.*') # .select('tasks.*') required for pg_search
.joins(:project => :user)
.includes(:project => :user)
.merge(Project.enabled_only.filter_by_location(#geo).search(params[:q]))
.order_results(sort)
In my Project model I have:
scope :distance_from, ->(latitude, longitude) {
select(%{
ST_Distance(
ST_GeographyFromText(
'SRID=4326;POINT(' || projects.longitude || ' ' || projects.latitude || ')'
),
ST_GeographyFromText('SRID=4326;POINT(%f %f)')
) AS distance
} % [longitude, latitude])
}
scope :near, ->(latitude, longitude, distance_in_meters = 1000) {
where(%{
ST_DWithin(
ST_GeographyFromText(
'SRID=4326;POINT(' || projects.longitude || ' ' || projects.latitude || ')'
),
ST_GeographyFromText('SRID=4326;POINT(%f %f)'),
%d
)
} % [longitude, latitude, distance_in_meters])
}
def self.filter_by_location(geo_location)
scoped = self.all
if geo_location.present?
scoped = scoped.distance_from(geo_location[:lat], geo_location[:lng])
scoped = scoped.near(geo_location[:lat], geo_location[:lng])
end
scoped
end
I then have the following in my Task model:
scope :distance_order, -> { order('distance') }
def self.order_results(sort)
# order scopes are appended
scoped = self.all.reorder('')
# check sql for search and distance fields
search_performed = scoped.to_sql.downcase.include?(' pg_search_rank')
distance_calculated = scoped.to_sql.downcase.include?(' distance')
if sort == 'rel'
# rel,dist
scoped = scoped.search_rank_order if search_performed
scoped = scoped.distance_order if distance_calculated
else
# dist,rel
scoped = scoped.distance_order if distance_calculated
scoped = scoped.search_rank_order if search_performed
end
scoped = scoped.name_order
scoped
end
This works fine for my app to sort results by proximity.
Distance is one of the columns in the sql select produced by the AR query, along with tasks.* and distance is being used correctly to sort results but I'm not sure how to display the distance in my view.
If I do <%= result.distance.to_s %>, it says distance is an undefined method. I don't have any joy with <%= result.project.distance.to_s %> either. Whereas <%= result.task_field %> and <%= result.project.project_field %> work fine.
I haven't seen too much use of both .joins() and .includes() at the same time in the RoR world but it did allow me to reduce the number of db calls whilst still producing the correct sql select statement...in my case anyway - that's why they are both used.
Am I missing something?
Is it the complexity of my AR query causing it?
Am I missing something in my Project or Task model to allow the virtual/calculated distance field to be display-able?
Thanks
The complex structure was replaced by a database view.
More details of how to do this can be found at this tutorial (http://pivotallabs.com/database-views-performance-rails/) and in one of my other SO questions here (Connecting database view with polymorphic model in rails).

Passing a list in a url inside a TokenInput with Django, he only pass the last one

I am using jquery-tokeninput as an autocomplete to retrieve some objects in my app.
My js code to initialize the autocomplete is this:
function initialize_search(model, input_busca) {
var url = reverse('autocomplete.'+model) + "?tipos[]=almoxarifado&tipos[]=estoque";
var data = $(input_busca).data('tokeninput');
$(input_busca).tokenInput(url, {
hintText: 'Start to type',
preventDuplicates: true,
queryParam: 'name',
noResultsText: 'No results',
searchingText: 'Search',
prePopulate: data
});
}
All I want is to receive the parameter 'tipos[]' in my view, like this:
types = request.GET.getlist('tipos[]')
And receive this:
[u'almoxarifado', u'estoque']
But when i do this, he only gives me the last one and not all the list, in this case:
[u'estoque']
This is how I call the autocomplete function inside the js:
inicializa_busca('endereco', $("#id_enderecos"));
You must be aware that, ajax is to pass small data, check the size of this list, maybe is better an full post submission!

Count an Attribute on a nested form?

Rails 3.2.12 and Ruby 1.9.3 and Haml
I would like to use the count of attribute to control the display of a 'link_to "remove"', but I am having problems with setting up the logic.
Following is some code from my form as it is currently:
.field
= codeline.label :name, "Units Alloc"
%br/
= codeline.text_field :units_alloc, :precision => 6, :scale => 2, :size => 10,
:class => "ui-state-default"
= codeline.hidden_field :_destroy
= link_to "remove", '#', class: "remove_fields"
this works well but I have the 'remove' link showing up and I would prefer it to only show if there are two :units_alloc attributes.
This is what I tried:
.field
= codeline.label :name, "Units Alloc"
%br/
= codeline.text_field :units_alloc, :precision => 6, :scale => 2, :size => 10,
:class => "ui-state-default"
- if :units_alloc.count > 1
= codeline.hidden_field :_destroy
= link_to "remove", '#', class: "remove_fields"
and here is my error:
NoMethodError in Contracts#new
Showing /home/tom/rails_projects/tracking/app/views/contracts
/_codeline_fields.html.haml where line #9 raised:
undefined method `count' for :units_alloc:Symbol
if I use units_alloc in the argument instead of the symbol, I still get an error:
NameError in Contracts#new
Showing /home/tom/rails_projects/tracking/app/views/contracts
/_codeline_fields.html.haml where line #9 raised:
undefined local variable or method `units_alloc' for
#<#<Class:0xadbde90>:0xa8956e8>
I tried to use 'codeline.units_alloc' but this did not work and the same error was flagged.
Any suggestions, or pointers to help me resolve this issue?
Thanks.
Solution: Thanks to James Scott Jr.
app/controller/contracts_controller.rb
def New
#show_remove = false
....
....
end
app/views/contracts/_codelines_fields.html.haml
.field
= codeline.label :name, "Units Alloc"
%br/
= codeline.text_field :units_alloc, :precision => 6, :scale => 2, :size => 10,
:class => "ui-state-default"
- if #show_remove
= codeline.hidden_field :_destroy
= link_to "remove", '#', class: "remove_fields"
- else
- #show_remove = true
And that did it ... the remove button only shows in the second and subsequent row of attributes.
By the time you're in the form (partial), codeline doesn't refer to an instance the instance of Codeline that the form (partial) is for, but an instance of an ActionView::Helpers::FormBuilder that simple knows how to associate information the the instance of Codeline. You knew that because in the first line of the partial, you have codeline.object.build_code.
So, if you want to access the information about the units_alloc associated, you would access them with codeline.object.units_alloc. That will give you your data for your conditional.
I would just like to add that if the purpose of your anchor tag is to remove elements from a form list using some javacscript, you might be using the wrong control for it. Anchor tags are not form elements, they should point to resources/content and are not there to be used as animation/client side behaviour triggers. According to the use case you describe, an input tag type=button would be a much more appropriated element for what you seem to be trying to achieve.