I currently have a vendor, which can have any number of tags attached to it. However, I also want the user to be able to add extra tags on the form. I had previously done this with fields_for and text fields in the form, and accepts_nested_attributes in the controller, but this led to tags getting duplicated when a tag with the same name was added to two different vendors. I know this happened because each vendor could only see the tags that it owned, so it did not know the IDs of the other tags.
Now, I have switched to a select, which lists all possible tags, and pass in a list of ownership IDs to the controller. However, I cannot add new tags anymore, since it cannot find the IDs of the new tags if they aren't added to the database first. It seems that I cannot use fields_for to build the options within the select, so I'm kind of stuck on how to handle this. I've looked into using AJAX to create the tag using the remote: true option inside form_for, but it seems that forms within forms are not supported.
Here are the basic model relationships:
class Vendor < ActiveRecord::Base
has_many :vendor_ownerships
has_many :ownerships, through: :vendor_ownerships
end
class Ownership < ApplicationRecord
has_many :vendor_ownerships
has_many :vendors, through: :vendor_ownerships
end
class VendorOwnership < ApplicationRecord
belongs_to :vendor
belongs_to :ownership
end
Here is my form partial (simplified). It currently tries to use nested forms, but it does not work.
= form_for #vendor do |f|
#form_elements_div
.form_group.element_div
= f.label :name
= f.text_field :name
#ownerships.element_div
= f.collection_select :ownership_ids, Ownership.all, :id, :name, {}, {multiple: true}
#new_ownerships.element_div
-# How do I add the new tag/ownership here?
= form_for :ownership, url: ownerships_path, remote: true do |ff|
= ff.text_field :new_ownership_field
= ff.submit
#submit_div.form_group
= f.submit class: 'btn btn-success'
Theoretically, the nested form for adding a new tag would trigger the controller action create inside the Ownership model, but the submit button for that form always triggers the create for the outer Vendor model.
Edit: Here is the HTML body currently created by my code.
<body>
<body id='vendorsBody'>
<div id='form_div'>
<h2>Edit Vendor</h2>
<form class="edit_vendor" id="edit_vendor_1" action="/vendors/1" accept-charset="UTF-8" method="post">
<input name="utf8" type="hidden" value="✓" />
<input type="hidden" name="_method" value="patch" />
<input type="hidden" name="authenticity_token" value="PzG968HknJ5wCYt37g7RL8J4/00rmcnIO6T02owt5HBh9FUsXfWd00WZW1k/vM+o4RktfbKPBEcWk4BdCfYnhg==" />
<div id='form_elements_div'>
<div class='form_group element_div'>
<label for="vendor_name">Name</label>
<input type="text" value="Vendor 1" name="vendor[name]" id="vendor_name" />
</div>
<div class='element_div' id='ownerships'>
<input name="vendor[ownership_ids][]" type="hidden" value="" />
<select multiple="multiple" name="vendor[ownership_ids][]" id="vendor_ownership_ids">
<option selected="selected" value="1">Type 1</option>
<option selected="selected" value="2">Type 2</option>
<option selected="selected" value="3">Type 3</option>
</select>
</div>
<div class='element_div' id='new_ownerships'>
<form action="/ownerships" accept-charset="UTF-8" data-remote="true" method="post">
<input name="utf8" type="hidden" value="✓" />
<input type="text" name="ownership[new_ownership_field]" id="ownership_new_ownership_field" />
<input type="submit" name="commit" value="Save Ownership" data-disable-with="Save Ownership" />
</form>
</div>
<div class='form_group' id='submit_div'>
<input type="submit" name="commit" value="Update Vendor" class="btn btn-success" data-disable-with="Update Vendor" />
<button class='btn btn-danger' id='cancel_button' onclick='confirmVendorCancel()' type='button'>Cancel</button>
</div>
</div>
</form>
</div>
</body>
</body>
Related
The following form allows the changing of an attribute vie UJS, the returning block of HTML is rendered correctly
<% #product.productviews.each do |productview| %>
<%= form_with(url: update_productview_products_path(productview_id: productview.id), method: :patch) do |form| %>
<%= productview.active %> <%= form.check_box :active %>
<%= form.submit t('update') %>
<% end %>
<% end %>
Class Product is a parent of has_many :productviews. context: rails 6.1.3
However when refreshing the page the check_box is invariably set to false, notwithstanding the value of the attribute:
<form action="/products/update_productview?productview_id=1" [...]
true <input name="active" type="hidden" value="0" /><input type="checkbox" value="1" name="active" id="active" />
<form action="/products/update_productview?productview_id=2" [...]
true <input name="active" type="hidden" value="0" /><input type="checkbox" value="1" name="active" id="active" />
<form action="/products/update_productview?productview_id=3" [...]
true <input name="active" type="hidden" value="0" /><input type="checkbox" value="1" name="active" id="active" />
<form action="/products/update_productview?productview_id=4" [...]
false <input name="active" type="hidden" value="0" /><input type="checkbox" value="1" name="active" id="active" />
Which is unexpected. Rails guides specify that Array parameters do not play well with the check_box helper. This instance is not a case of array parameters, although it is an array of forms.
However switching to <%= form.check_box_tag "active" %> or <%= form.check_box_tag :active %> will return
undefined method `check_box_tag' for #<ActionView::Helpers::FormBuilder:
which again seems contrary to what the Rails guides purport
Can check_box be used in an array of forms? How can this checkbox show the value of the attribute on page load?
you need to pass the model to the form
<%= form_with(url: update_productview_products_path(productview_id: productview.id), method: :patch, model: productview) do |form| %>
if this does not work you can pass a checked into the check_box input but I advise to use the first option if its working
<%= form.check_box :active, checked: productview.active %>
problem: I have a form but the submit button doesn't do anything.
i instantiate the class the form is for in the employee_controller controller.
def employee
#body_class = "employee membership"
#employee_contact_form = CorporateContactForm.new
end
I create the form in the page the above controller action serves
= simple_form_for [#employee_contact_form] do |f|
= f.input :firstname
= f.button :submit
In my routes I set the resources for the contact forms
resources :corporate_contact_forms
I then have a controller that serves the form
class CorporateContactFormsController < ApplicationController
def create
raise
end
I am aware there is no code in the corporatecontactcontroller, but the submit button should at least fire to an error. It doesn't do anything.
This feels like such a simple problem, and surely it is.
What am I missing?
update
html output
<form>
<form accept-charset="UTF-8" action="/corporate_contact_forms" class="simple_form new_corporate_contact_form" id="new_corporate_contact_form" method="post"><div style="display:none"><input name="utf8" type="hidden" value="✓" /><input name="authenticity_token" type="hidden" value="7iMwWQOuyzV3jJt4jTtr9MGvI129hPaG+m+Pe2D3YyM=" /></div> <div class="input string optional corporate_contact_form_firstname"><label class="string optional" for="corporate_contact_form_firstname">Firstname</label><input class="string optional" id="corporate_contact_form_firstname" maxlength="255" name="corporate_contact_form[firstname]" size="255" type="text" /></div>
<input class="button" name="commit" type="submit" value="Create Corporate contact form" />
</form>
</form>
According to the documetation (http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-form_for), you can do something like this to force the form to go to CorporateContactFormsController#create
<%= simple_form_for #employee_contact_form, url: corporate_contact_forms_path, method: :post do |f| %>
# awesome code...
<% end %>
Also I'm not sure if the f.button :submit has something to do, the default for submitting is f.submit
Hello I have a really annoying problem with my rails 3.0 form. I'm using CKEditor to let the user edit html content of their page. Everything was working fine in rails 2 he made a lot of pages with html content. But then I needed to update the rails gem to 3.0.1 since the was a need for that (server admins updated to rails 3 and removed 2).
After this change He wanted to edit the pages for a new season (tourism oriented business). Some of the pages could't be updated I get a
403 Forbidden
Access to this resource on the server is denied!`
It drives me nuts, I tried every solution that could be relevant but still no luck.
I figure it could has to do with the html content submitted with form because when I delete the content and put some simple paragraph text it works OK. But I have no idea what could it be.
Here's a sample form
<form accept-charset="UTF-8" action="/pages/113" class="jNice" id="edit_page_113" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /><input name="_method" type="hidden" value="put" /><input name="authenticity_token" type="hidden" value="w5ZUDHYHnFKHhLQc6UO/a3zwbN5p6JMgKYUWlVhbMiU=" /></div>
<fieldset>
<p>
<label for="page_category_id">Kategoria:</label>
<select id="page_category_id" name="page[category_id]"><option value=""></option>
<option value="13">School And Study Tours Groups</option>
<option value="23" selected="selected">Regular & Group Tours To Poland </option>
<option value="14">Jewish History And Heritage Tours</option>
</select>
</p>
<p>
<label for="page_name">Nazwa podstrony:</label>
<input id="page_name" name="page[name]" size="30" type="text" value="Poland in a week - the Southern face" />
</p>
<p>
<label for="page_cities">Miasta imprezy:</label>
<input id="page_cities" name="page[cities]" size="30" type="text" value="Warsaw - Krakow - Wieliczka - Auschwitz - Czestochowa" />
</p>
<p>
<label for="page_keywords">Słowa kluczowe:</label>
<input id="page_keywords" name="page[keywords]" size="30" type="text" value="Poland tour, tour of Warsaw, tours of Cracow, czestochowa Jasna gora tour" />
</p>
<p>
<label for="page_description">Skrócony opis:</label>
<input id="page_description" name="page[description]" size="30" type="text" value="2012 tour to Poland with visit to Wieliczka Salt Mine and Czestochowa " />
</p>
<p>
<label for="page_tour_of_the_month">Tour of the month na stronie głównej?:</label>
<input name="page[tour_of_the_month]" type="hidden" value="0" /><input id="page_tour_of_the_month" name="page[tour_of_the_month]" type="checkbox" value="1" />
</p>
<p>
<label for="page_html_body">Zawartość:</label>
<textarea class="ckeditor" cols="40" id="page_html_body" name="page[html_body]" rows="20">test</textarea>
</p>
<p>
<label for="page_published">Opublikowana?:</label>
<input name="page[published]" type="hidden" value="0" /><input checked="checked" id="page_published" name="page[published]" type="checkbox" value="1" />
</p>
<p>
<label for="page_show_request_link">Pokaż link rezerwacyjny?:</label>
<input name="page[show_request_link]" type="hidden" value="0" /><input checked="checked" id="page_show_request_link" name="page[show_request_link]" type="checkbox" value="1" />
</p>
</fieldset>
<p><input id="page_submit" name="commit" type="submit" value="edytuj" /></p>
</form>
Here's the content of the routes.rb file
Gfp3::Application.routes.draw do
resources :newscasts do
get :publish, :on => :member
end
resources :links
resources :payments
resources :fronts
resources :categories do
collection do
:sort
end
end
resources :pages do
get :publish, :on => :member
end
resources :menus
match 'login',:to=>'index#login'
match 'logout', :to=>'index#logout'
match 'images', :to=>'images#index'
match 'images/upload', :to=>'images#upload'
match 'front_page',:to=>'front_page#index'
match 'search',:to=>'index#search'
match ':controller(/:action(/:id(.:format)))'
root :to => 'index#index'
match ':id',:to=>"pages#show"
end
Theese are the gems used in the app
gem 'mongrel'
gem 'rails', '3.0.1'
gem 'haml'
gem "will_paginate", "3.0.pre2"
gem 'mysql',"2.8.1"
Look like routes wrong defined or not defined
I am trying to create a form that serves as confirmation for the destroy method on a controller. In my routes I have:
resources :leagues do
get 'delete', :on => :member
end
In my delete.html.erb, I have the following for:
<% form_for current_league, :html => {:method => :delete} do |form| %>
<%= form.submit 'Yes' %>
<%= form.submit 'No', :name => 'cancel' %>
<% end %>
current_league is a helper function defined by:
def current_league
#current_league ||= League.find_by_id(params[:id])
end
So the problem is that the form that is generated only edits the league model, as seen by the form method="post".
<form accept-charset="UTF-8" action="/leagues/1" class="edit_league" id="edit_league_1" method="post">
<div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" />
<input name="_method" type="hidden" value="delete" />
<input name="authenticity_token" type="hidden" value="abcdefg" />
</div>
<input id="league_submit" name="commit" type="submit" value="Yes" />
<input id="league_submit" name="cancel" type="submit" value="No" />
</form>
How can I fix this?
I think that will already work. As in rails guide http://guides.rubyonrails.org/form_helpers.html#how-do-forms-with-patch-put-or-delete-methods-work-questionmark
However, most browsers don’t support methods other than “GET” and “POST” when it comes to submitting forms.
Rails works`around this issue by emulating other methods over POST with a hidden input named "_method", which is set to reflect the desired method:
as you see in the output form there is
<form accept-charset="UTF-8" action="/leagues/1" class="edit_league" id="edit_league_1" method="post">
....
<input name="_method" type="hidden" value="delete" />
....
</form>
When reading this variable, rails understood that this is a DELETE method, not a POST method. even though the form it self is a POST.
How do I change the order of the input element that simple form generate?
Because the hidden checkbox does block for clicking the label.
My simple_form code:
<label>
<span>Company<b></b></span>
<%= f.check_box :company_is_true %>
</label>
The form simple form generate:
<label>
<span>Company<b>0</b></span>
<input type="hidden" value="0" name="search[company_is_true]">
<input type="checkbox" value="1" name="search[company_is_true]" id="search_company_is_true">
</label>
That I want to generate, that works when clicking on label:
<label>
<span>Company<b>0</b></span>
<input type="checkbox" value="1" name="search[company_is_true]" id="search_company_is_true">
<input type="hidden" value="0" name="search[company_is_true]">
</label>
I don't know how to add a comment to the list of comments, but in response to:
The user should be able to click on the label to check and uncheck the checkbox – Rails
beginner 1 hour ago
It's not the checkbox that prevents the user from clicking on that label, it's the lack of the for="" in
<label>
<span>Company<b></b></span>
<%= f.check_box :company_is_true %>
</label>
Either use <%= f.label %> as agmcleod mentioned, or add a for="" to the label:
<label for="search_company_is_true">
<span>Company<b></b></span>
<%= f.check_box :company_is_true %>
</label>
In a traditional html form, it should be structured something like this:
<label for="name">Name: </label>
<input type="text" name="name" />
The for attribute connects it to a field with either a name attribute or id attribute with that value you use in for. To do this in rails, use the following:
<%= f.label :company_is_true, 'Company' %>
<%= f.check_box :company_is_true %>