I'm trying to map a form_for to a specific controller and action. I've got the resources: apikey in the routes. All the solutions I've found don't seem to work. The form is placed inside a view of which the parent folder name doesn't correspond to the correct controller. Here is my form with my not working solution:
<%= form_for #key, url: { controller: :apikey, action: :update }, remote: true do |f| %>
<%= f.label :userkey, "Key" %>
<%= f.text_field :userkey %>
<%= f.submit "Update" %>
<% end %>
Here is my controller:
class ApikeyController < ApplicationController
def index
end
def update
respond_to do |format|
if #key.update(apikey_params)
format.js
else
format.html { render action: 'edit' }
end
end
end
private
def apikey_params
params.require(:apikey).permit(:userkey)
end
end
This is the log I get in the console:
Started GET "/accounts?utf8=%E2%9C%93&_method=patch&apikey%5Buserkey%5D=thekey&commit=Update"
As you can see, it doesn't call the apikey but the accounts controller. What am I doing wrong?
Update
A little weird, as I didn't really change anything, I now get this error when opening the site:
No route matches {:action=>"update", :controller=>"apikey"}
This is my rake routes:
apikey_index GET /apikey(.:format) apikey#index
POST /apikey(.:format) apikey#create
new_apikey GET /apikey/new(.:format) apikey#new
edit_apikey GET /apikey/:id/edit(.:format) apikey#edit
apikey GET /apikey/:id(.:format) apikey#show
PATCH /apikey/:id(.:format) apikey#update
PUT /apikey/:id(.:format) apikey#update
DELETE /apikey/:id(.:format) apikey#destroy
Update 2
Originally I had the form inside a bootstrap modal, like this:
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Change API key</h4>
</div>
<div class="modal-body">
<form role="form">
<div class="form-group">
<%= form_for #key, method: "post", remote: true do |f| %>
<%= f.label :userkey, "Key" %>
<%= f.text_field :userkey, class:"form-control", id:"apikeyinputfield" %>
<%= f.submit "Update", class: "btn btn-success btn-sm" %>
<% end %>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" id="submitnewapikey" data-dismiss="modal" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
If I delete the surrounding modal, the form automatically to map to the correct controller and action. This is not the case when surrounded by the modal. Really weird. Maybe the modal JS code messes up the form_for JS code.
You don't actually need to specify the url in form_for.
If no url is specified form_for will automatically identify which controller and method based on the #key parsed to it, regardless of what view the form is located.
<%= form_for #key, remote: true do |f| %>
<%= f.label :userkey, "Key" %>
<%= f.text_field :userkey %>
<%= f.submit "Update" %>
<% end %>
the piece code above can have the following outcomes:
if #key is a new record ( #key.new_record? returns true):
The form will send the request to ApikeyController create action
if #key is a not a new record ( #key.new_record? returns false), which is your case:
The form will send the request to ApikeyController update action
More info can be found here.
Hope this can help you.
Related
All, i am facing an issue with passing a parameter into my Modal to sent the value of a field. I am able to pass and lookup the value via params if i go to new page where i can find the value from the URL params. But i am trying to use the same logic but in a modal and i can't seem to get it to work.
_my comments partial has the following
<% Reply.all.each do |reply|%>
<% if reply.parent_id == comment.id%>
<p class="feed-s-connection-update-item__headline Sans-1px-black-55%">
<%= image_tag(User.find(reply.user_id).avatar,:size => "20x20",class: "image-responsive") %>
<%=reply.body %>
</p>
<%end%>
<%end%>
<% from_reply_form ||= nil %>
<% unless from_reply_form %>
<p>
<%= link_to 'reply', new_reply_path( :id => comment.id) %>
</p>
<%= link_to 'Add release', new_reply_path(#reply,:id => comment.id), {:remote => true, ':id' => 'comment.id','data-toggle' => "modal", 'data-target' => '#replyModal'} %>
<% end %>
<div id="modal-window" class="modal hide fade" role="dialog" aria- labelledby="myModalLabel" aria-hidden="true"></div>
</div>
</li>
</ul>
<%end%>
I am trying this out using this link:
<%= link_to 'Add release', new_reply_path(#reply,:id => comment.id), {:remote => true, ':id' => 'comment.id','data-toggle' => "modal", 'data-target' => '#replyModal'} %>
If i use i am taking to the new page and will have the params in the url which works fine
url: https://hidemyurldevel/replies/new?id=72
<%= link_to 'reply', new_reply_path( :id => comment.id) %></p>
I am able to see the same URL when i try the other URL where remote is true, but i am not able to see the PARENT_ID populated.
Replies_controller - know this part i need to remove the respond but i have it break here so i can see whats returning
def create
#reply = Reply.new(reply_params)
if #reply.save
flash[:notice] = "thanks for reply"
respond_to do |format|
format.js
redirect_to :back
end
end
end
def new
#reply = Reply.new
#comment = Comment.find(params[:id])
#userid = current_user.id
end
Here is the Modal i call
for some reason the value is not populated into the Modal
<%= form_for(#reply) do |f| %>
<div id="replyModal" class="modal fade" tabindex="-1" role="dialog" aria- hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria- hidden="true">×</button>
Post A Reply
</div>
<div class="modal-body">
<form class="form center-block">
<div class="form-group">
Post <%= f.text_area :body, class:"form-control input-lg" %>
<%= f.hidden_field :user_id, :value =>#userid %>
<%= f.hidden_field :parent_id, :value =>#comment.id %>
</div>
<div class="field">
</div>
</form>
</div>
<div class="modal-footer">
<div>
<button class="btn btn-primary btn-sm" data-dismiss="modal" aria-hidden="true">reply</button>
<ul class="pull-left list-inline"><li><i class="glyphicon glyphicon-upload"></i></li><li><i class="glyphicon glyphicon-camera"></i></li><li><i class="glyphicon glyphicon-map-marker"></i></li></ul>
</div>
<div class="actions">
<%= f.submit class: "btn btn-primary btn-sm"%>
</div>
</div>
</div>
</div>
<%end%>
I can't seem to be able to use the parent_id from the URL and pass it into the
This works fine if you go to the new page but not when i try passing it into the URL to the controller. Please help!
So guys i solve my problem... I am not sure if this is the right way to go, but i wasn't setting the comment parameters and it was Nill to begin with.... i just initialize the comment and set it to the instance of the comments and that works..
Excerpt
i am iterating the comment
then in my reply section where i add a comment field next to each comment i am able to pass the value in the URL
<%#comment = comment%>
<%= link_to 'Add release', new_reply_path(:#comment => comment), {:remote => true, :id => comment.id,'data-toggle' => "modal", 'data-target' => '#replyModal'} %>
I'm getting an error on my edit user modal that says that the first argument can't be nil; however, the form works and pulls the information as expected. The setup is like this:
1) I have a table that summarizes employees
2) each employee has a modify action
3) the modify action opens up a modal with the edit form
The form works and users are able to edit employees. However, every time it's open I get an internal error notification saying that the first argument can't be nil or empty. just to be sure, I'm displaying the employee name in the edit modal to confirm it's not nil (and it's not). The problem is, I'm getting notifications for internal server errors caused by this issue although somehow the form is working.
Any thoughts on what could be causing this and how to fix it?
Employee table code:
<tr>
<td> <%= employee.name %> </td>
<td> <%= employee.status ? t(:active) : t(:inactive) %> </td>
<td> <%= mmm_dd_yy_date(employee.created_at) %> </td>
<td> <%= mmm_dd_yy_date(employee.updated_at) %> </td>
<td> <%= link_to t(:edit), '#', "data-toggle" => "modal", "data-target" => "#EditModal_#{employee.id}", "data-remote" => edit_employee_path(employee) + "#modal-edit-form" %> |
<%= link_to t(:remove), employee, method: :delete, data: { confirm: t(:confirm_remove_employee, name: employee.name)} %>
<!-- Modal -->
<div id='<%= "EditModal_#{employee.id}" %>' class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title"><%= t(:edit_employee) %></h4>
</div>
<div class="modal-body">
<%=render partial: 'edit_form', locals: {employee: employee} %>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal"><%= t(:close) %></button>
</div>
</div>
</div>
</div>
</td>
</tr>
Form modal code:
<div id= "modal-edit-form">
<%= employee.name %>
<%=form_for(employee) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class = "row" >
<div class = "col-xs-6">
<%= f.label :name%>
<%= f.text_field :name, class: 'form-control' %>
<%= f.label :status %>
<%= f.collection_select :status, {true: t(:yes), false: t(:no)}, :first, :last, selected: employee.status %>
<%= f.submit t(:update), class: "btn btn-primary"%>
</div>
</div>
<% end %>
</div>
The code looks good to me.
--
The one thing I would say is that including form_for multiple times on the same page is a big no-no - a bunch of conflicts will occur (id etc).
I would personally move the functionality to your employees#edit action as ajax:
#app/controllers/employees_controller.rb
class EmployeesController < ApplicationController
respond_to :js, :html, :json, only: :edit
def edit
#employee = Employee.find params[:id]
respond_with #employee
end
end
#app/views/employees/edit.js.erb
$("<%=j render 'edit' %>").appendTo("body");
// fire modal
#app/views/employees/edit.html.erb
<div id='<%= "EditModal_#{employee.id}" %>' class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title"><%= t(:edit_employee) %></h4>
</div>
<div class="modal-body">
<%=render partial: 'edit_form', locals: {employee: #employee} %>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal"><%= t(:close) %></button>
</div>
</div>
</div>
</div>
#app/views/employees/index.html.erb
<%= link_to t(:edit), '#', data: { toggle: "modal", target: "#EditModal_#{employee.id}", remote: edit_employee_path(employee) + "#modal-edit-form" }, remote: true %>
This way, you'll only be appending the edit forms when you render them.
I've got a page showing details for every #user. Each user has an enrolment, which can has a comment. When I e.g. do this:
<% #user.each do |u| %>
<% the_enrolment = Enrolment.where(user_id: u).first %>
<% end %>
Then in every iteration the enrolment is a different enrolment, as the user changes in every iteration. So far, so simple.
But when I pass this enrolment variable (while looping through) to a partial which contains a form, like this:
<%= render 'the_partial', enrolment: the_enrolment %>
With this form (in the partial view):
<%= form_for enrolment, :url => the_path, remote: true do |f| %>
<%= f.hidden_field :id %>
<%= f.text_area :comment %>
<%= f.submit "Save" %>
Then, in the finally rendered page, every form uses the same enrolment. (They all have the same id and every text_are is pre filled with the content of one of them. What am I doing wrong here?
The complete iteration looks like this:
#user.each do |u|
the_enrolment = Enrolment.where(user_id: u).first
<%= the_enrolment %> # correct id
<%= render 'the_partial', enrolment: the_enrolment %>
end
Thank you very much!
Update
Here is an update with the newest informations. The problem seems to be that the form is placed inside a twitter bootstrap modal. Here is the whole partial:
<%= enrolment.id %> # here it's the correct id
<div id="myModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel">Admin Comment</h3>
</div>
<%= form_for enrolment, :url => the_path, remote: true do |f| %>
<div class="modal-body">
<p>
<%= "enrolment in modal: #{enrolment.id}" %> # at this place the id is ALWAYS the id of the very first enrolment
<%= f.hidden_field :id %>
<%= f.text_area :comment_admin %>
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
<%= f.submit "Save", class: "btn btn-success", id: "admin-comment-submit-button" %>
</p>
</div>
<% end %>
</div>
If I delete everything on this page concerning the modal, the form works.
I have a Rails app with Expenses that belongs_to Vendors.
While the user is adding a new Expense, they might need to add a new Vendor.
I thought I could just add a button and a Vendor partial to the Expense form.
Like this:
<%= simple_form_for #expense, :html => {:class => 'form-horizontal'} do |f| %>
<div class="span5">
<a data-toggle="modal" href="#vendorform">
<p class="pull-right btn btn-primary btn-mini">New Vendor</p></a>
<%= render :partial => "vendors/vendorform" %>
</a>
<%= f.association :vendor, :label_method => :vendor_name, :label => 'Vendor', collection: Vendor.order('vendor_name ASC') %>
The _vendorform.html.erb looks like this:
<div id="vendorform" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="vendorformLabel" aria-hidden="true">
<div class="modal-header">
<a class="close" data-dismiss="modal">×</a>
<h4 id="vendorformLabel">Add Vendor</h4>
</div>
<div class="modal-body">
<%= simple_form_for Vendor.new do |f| %>
(bunch of fields)
</div>
<div class="modal-footer">
<%= f.submit 'Save Vendor', :class => 'btn btn-mini btn-primary' %>
<a class="btn btn-mini" data-dismiss="modal" href="#">Close</a>
<% end %>
</div>
</div>
This partial shows up OK. But, the Vendor record doesn't get created.
The submit of the partial actually somehow triggers the submit for the Expense. The page comes back with all of the required Expense fields red.
I think it's posting to the Expenses controller when the f.submit button in the Vendor partial is pressed !!!
Do I need something in the Expense controller?
Or is there a better way?
Thanks for the help!
Are you sure the vendor partial is in the same folder as the expense form? If not you should have
<%= render :partial => "folder/vendorform" %>
When you have nested attributes, you should use the simple_fields_for method which help manage associations. Then, remove the submit button for the vendor form and add it to the expense form instead. So the vendor form would be -
<div class="modal-body">
<%= simple_form_for Vendor.new do |f| %>
(bunch of fields)
<% end %>
</div>
I have link_to and when i click link then div(id="edit_comment_form") showed (This div is form for user edit content) and i want pass params[:cc] from link_to to div This is source code.
<%= link_to "Edit", "#edit_comment_form", :class => "btn", "data-toggle" => "modal" %>
<div id="edit_comment_form" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<%= form_tag({controller: "comments", action: "edit"}, method: "get", class: "xxx") do %>
<div class="modal-body">
<%= text_area_tag :comment, "" ,rows: 10,:style => "width:515px; resize: none;",:placeholder => "Please type your comment." %>
<%= hidden_field_tag(:cc, params[:cc]) %> ### I want params[:cc]
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
<%= submit_tag "Vote",:class => "btn btn-primary" %>
</div>
<% end %>
How can i pass params to div. Please help me!
You will need to use "data-cc" if you want it to be an HTML attribute on the <a> element and not break the validity of your HTML. You will need to write a custom javascript onclick handler if you want to pass data into the form on click, regardless of how you structure the data into the <a> element that link_to creates.
This post states you shouldn't use data-toggle when you want additional functionality, to prevent some other issues that will arise. You will likely need to build out a full onclick event handler yourself.