rails 4 ransack gem, undefined path error - ruby-on-rails-4

I have rails 4 app with an Events model that I want to make searchable on a variety of fields using the Ransack gem.
my controller action:
def index
#search = Event.ransack(params[:q])
#events = #search.result(distinct: true)
end
my search form in index.html.erb:
<%= search_form_for #search do |f| %>
<%= f.text_field :name_cont, class: "radius-left expand", placeholder: "Event Name" %>
<% end %>
However, in loading the page, I get the following error:
ActionView::Template::Error (undefined method events_path' for #<#:0x007fc08b3fa838>): 1: Events 2: 3: <%= search_form_for #search do |f| %> 4: <%= f.text_field :name_cont, class: "radius-left expand", placeholder: "Event Name" %> 5: <% end %> 6: app/views/events/index.html.erb:3:in_app_views_events_index_html_erb___2056451196739971413_70232473324180'
when I rake routes, I get:
events_show GET /events/show(.:format) events#show
events_index GET /events/index(.:format) events#index
so i assume if I could get this form to point to events_index_path, it would work as expected.
what do I need to do to specify the correct path for the form?

Tbh i am not sure what i did to get this working. here is my controller index action now, which includes a distance/location search feature:
def index
if params[:within].present? && (params[:within].to_i > 0)
#search = Event.near(params[:location],params[:within]).search(params[:q])
else
#search = Event.search(params[:q])
end
#events = #search.result
end

Related

adding parameters to search form for persistency

A form targets a results page:
<%= form_tag results_interventos_path do %>
From: <%= date_select :intervento, :from, { order: [:day, :month, :year], default: Date.today-31, start_year: Time.now.year-1, end_year: Time.now.year, datetime_separator: " " } %>
To: <%= date_select :intervento, :to, { order: [:day, :month, :year], default: Date.today-30, start_year: Time.now.year-1, end_year: Time.now.year, datetime_separator: " " } %>
<%= collection_select(:intervento, :invoicestate_id, Invoicestate.all, :id, :nome, prompt: "tutti") %>
the results are routing to a paginated (with will_paginate) page presently defined as:
post :results
Goal: to maintain the search parameters in the URL so that any action taken from the results page can be returned to with a link defined by :back symbol
with proper routing, this is resolved:
get :results
form should also point accordingly to the proper method
<%= form_tag results_interventos_path, method: :get do %>
otherwise a post is attempted.

Rails: Conditional nested attributes in edit form

I have a model called Offer and another called PurchasinGroup
Offer has many PurchasingGroups
Offer accepts nested attributes for PurchasingGroups
While creating an offer you can add as many PurchasingGroups as you want.
PurchasingGroup has a boolean attribute called active.
while editing an Offer you can see all the created PurchasingGroups, however I want to let the user edit only the PurchasingGroups that are active, and do not display the inactive purchasing groups.
This is my edit action in offers_controller.rb:
def edit
#offer = Offer.find(params[:id])
end
And this is my form (only the part that matters):
<fieldset>
<legend>Purchasing groups</legend>
<%= f.fields_for :purchasing_groups do |builder| %>
<%= render partial: 'purchasing_group_fields', locals: { f: builder } %>
<% end %>
</fieldset>
In the edit form all the purchasing groups are being shown for edit, I want to show only those that are active I mean purchasing_group.active == true
How is the best way to do it?
<%= f.fields_for :purchasing_groups, #offer.purchasing_groups.where(active: true) do |builder| %>
<%= render partial: 'purchasing_group_fields', locals: { f: builder } %>
<% end %>
on the other hand, you can also add a association in your model
class Offer
has_many :active_purchasing_groups, class_name: "PurchasinGroup", -> { where(active:true) }
...
end
and then
<%= f.fields_for :active_purchasing_groups do |builder| %>
<%= render partial: 'purchasing_group_fields', locals: { f: builder } %>
<% end %>

Indicate that an uploaded file is present in edit form -- paperclip

In my current solution, I am able to put a checkbox in the edit form so that users can delete attachment. However, there is no indication for the user that a file has been uploaded, the name of that file, etc. so that he can decide whether to delete.
Right now the form look like this. The first material is an existing one, the next 3 are due to
def edit
#post = Post.find(params[:id])
3.times { #post.post_materials.new }
end
As you can see, it's very hard to distinguish between them. Ideally, I want the first material file name to appear somehow.
<%= form_for #post, :html => { :multipart => true } do |f| %>
<%= f.label :title %>
<%= f.text_field :title %>
Materials:
<ul>
<%= f.fields_for :materials, :html => { :multipart => true } do |materials_form| %>
<li>
<%= materials_form.label :asset %>
<%= materials_form.file_field :asset %>
<%= materials_form.label :_destroy, class: "checkbox inline" do %>
Remove attachment <%= materials_form.check_box :_destroy %>
<% end %>
</li>
<% end %>
</ul>
<%= f.submit "Submit", class: "btn btn-large" %>
<% end %>
Running paperclip's generator creates a migration to add 4 attributes on your model, as you can see here. These attributes are:
<attachment>_file_name
<attachment>_file_size
<attachment>_content_type
<attachment>_updated_at
So, If you ran the generator this way: rails generate paperclip post_material asset, on your PostMaterial model, you will have these attributes:
asset_file_name
asset_file_size
asset_content_type
asset_updated_at
Then, on your code you can do something like this:
if materials_form.object.asset.exists? #object represents the current post_material instance
#show a label with object.asset_file_name
else
#render materials_form.file_field :asset
end

ransack search # rails 4

When I am searching for gender field say "male", it searches for "male" and "female" as "male" keywork is in "female" too.
So How can I use ransack in rails so that it matches for exact keyword instead of any partial group of chars.
PS:similarly how can I enable or disable the exact or partial key match in RANSACK gem.
I believe you could just do
<%= search_form_for #q do |f| %>
<%= f.label :gender_eq, "Gender:" %>
<%= f.search_field :gender_eq %>
<% end %>
that will tell the search to look for the exact string of your input
Here is some of the info from the developer on how it's used.
https://github.com/activerecord-hackery/ransack#in-your-view
I believe the way you do your search is <%= (field_name)_cont ... %> cont means contains.
What you want is _eq, change your view into <%= (field_name)_eq ... %> and it should work.
For more info:
https://github.com/activerecord-hackery/ransack/wiki/Basic-Searching

Rails Update Model from Multiple Select Form: No implicit conversion of String into Integer

If Project has_many Genre through: GenresProject
and params are:
def project_params
params.fetch(:project, {}).permit(genres_projects_attributes: [:id, {genre_id: []})
end
and my submit form is:
<%= form_for #project do |f| %>
<%= f.fields_for :genres_projects_attributes do |ff| %>
<%= ff.select :genre_id, Genre.order(:id).collect{|g| [g.name, g.id]}, {}, { multiple: true } %>
<% end %>
<%= f.submit 'Update'%>
<% end %>
and my params look like this:
"project"=>{ ... "genres_projects_attributes"=>{"genre_id"=>["3", "5"]}} ... }
Should
project.update(project_params)
Automatically iterate through the genre_id array and create the appropriate GenresProject records?
If you don't have GenreProject record, then you will not get an id from the params.
Secondly, it will not automatically create the new Genre record or update one for you, I think. You should handle creating new record in the update action yourself. For example:
params[:project][:genre_id].each do |id|
unless GenreProject.find(id)
# create new record here
GenreProject.create
end
# other updating operations
end
Hope it works for you