adding parameters to search form for persistency - ruby-on-rails-4

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.

Related

No route matches [POST] "/basic_pages/basic_pages/home"

So I would simply like to post to my root. My problem is that if I try to do it the second time (first time works fine) I am posting /basic_pages/basic_pages/home instead of /basic_pages/home. Why does that happen and how do I fix this?
home.html.erb:
<h1>BasicPages#home</h1>
<p>Find me in app/views/basic_pages/home.html.erb</p>
<%= form_tag ('basic_pages/home') do %>
<%= text_field_tag :my_input %>
<%= submit_tag "Send input" %>
<% end %>
routes.rb
Rails.application.routes.draw do
root 'basic_pages#home'
post 'basic_pages/home'
get 'about' => 'basic_pages#about'
end
Hope this provides all the information necessary.
Instead of using form_tag ('basic_pages/home') use form_tag ('/basic_pages/home'). When you have posted the url is getting changed to /basic_pages/home, and then the form is again posting to /basic_pages/basic_pages/home, because of the relative path given to the form.
Try this
Rails.application.routes.draw do
post '/' => "basic_pages#home", as: "root"
get 'about' => 'basic_pages#about'
end
home.html.erb:
<%= form_tag ('/') do %>
<%= text_field_tag :my_input %>
<%= submit_tag "Send input" %>
<% end %>

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 %>

rails 4 ransack gem, undefined path error

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

Rails: param is missing or the value is empty because param appearing as "#<Edge:0xb2535b8>"

I'm using form for and the name of the form in the controller is appearing as "#", but I expect it to appear as :edge.
Here's my controller:
def new
#some_stuff
#edge = Edge.new
#some_stuff
end
def create
#edge = Edge.new(edge_params)
#edge.save
end
def edge_params
params.require(:edge).permit(:location_1_id, :location_2_id)
end
View:
<%= form_for( :edge, :url => {:action => 'create'}) do |f| %>
<ul>
<li>
<%= f.label :location_1_id %>
<%= collection_select(#edge, :location_1_id, #location, :id, :record_as_string) %>
</li>
<%= submit_tag(t(:create_edge)) %>
</ul>
<% end %>
Param req:
{"utf8"=>"✓", "authenticity_token"=>"blah",
"#"=>{"location_1_id"=>"91", "location_2_id"=>"92"},
"commit"=>"Create Edge", "action"=>"create",
"controller"=>"admin/edges", "floor_map_floor_id"=>"1"}
So the name of the parameter should be :edge but it's an object that I can't access.
Can anybody tell me what I'm missing?
Any help is appreciated.
You should be using the form block on your collection set like so
<%= f.collection_select(:location_1_id, #location, :id, :record_as_string) %>
(notice that you are calling the collection_select on the block variable f, and NOT passing in the #edge as the first argument).
In addition, because you are creating the object in new (#edge = Edge.new), you should just be using in your form, like so
<%= form_for( #edge, :url => {:action => 'create'}) do |f| %>
(although using :edge wasn't the cause of your problems, I suspect it was because you were using :edge and #edge in the same form. You need to be consistent, use one or the other)

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