open child form in new page - ruby-on-rails

I have a sponsor which can have many warranty management urls. I have implemented the sponsor form but having trouble to create urls child form. Problem is I need to create child in new page and show the list back to the main form. How do I do it?
My form:
<%= form_for #sponsor, url: polymorphic_path([:a, #sponsor]) do |form| %>
<%= form.file_field :logo %>
<%= link_to "Add Warranty Service URL", new_a_sponsor_warranty_management_url_path(#sponsor), class: 'button green right' %>
<% end %>
Routes:
resources :sponsors do
resources :warranty_management_urls, only: [:new,:edit,:create,:update,:destroy]
end
Controller:
def new
#sponsor = Sponsor.new
end
Currently this error pops up:
No route matches {:action=>"new", :controller=>"a/warranty_management_urls", :sponsor_id=>nil}, possible unmatched constraints: [:sponsor_id]

It looks like your route helper is incorrect. The documentation for resource route helpers may be helpful for your situation: https://guides.rubyonrails.org/routing.html#path-and-url-helpers
Have you tried running rake routes to get the list of available routes and route helpers? I imagine you need something more like:
<%= link_to "Add Warranty Service URL",
new_warranty_management_url_path,
class: 'button green right' %>
You can pass a sponsor_id param as an argument to the path helper, but that won't work unless the sponsor has been saved, which isn't true for a new record.

Related

Rails: Routing and form for custom controller method

I'm getting this error attempting to create a page that shows room details. Pressing on edit will triggger a popup window with prefilled values of the room clicked. And clicking save on the window will update data for that entry.
I'm not so sure how to predefine the id, I'm currently using jQuery to populate the form with current data of selected records.
No route matches {:action=>"save_details", :controller=>"rooms"}, missing required keys: [:id]
rooms/index.html.erb
<%= form_for(#room, url: save_details_room_path) do |f| %>
<% f.text_field :id, id:'edit-room-id', class:'d-none' %>
<% f.text_field :name, id:'edit-room-name' %>
<% f.text_area :desc, id:'edit-room-desc', style:'width: 90%; height: 8em; resize: none; float: bottom' %>
<%= f.submit 'Save', :class=>'btn btn-primary' %>
<% end %>
rooms_controller.rb
def save_details
logger.info ('Hello world')
#room= Room.find(params[:id])
#room.name = params[:name]
#room.description = params[:desc]
#room.save
redirect_to rooms_url
end
def show
#room = Room.find(prams[:id])
end
def index
#room = Room.all
end
routes.rb
resources :rooms do
get :save_details, on: :member
end
main.js
const name = $(this).data('name');
const desc = $(this).data('description');
const id = $(this).data('id');
$('#edit-room-id').val(id);
$('#edit-room-name').val(name);
$('#edit-room-desc').val(desc);
1ST EDIT:
Now I'm doing this another way which is just to simply pass the form as a url through, eg. /rooms/save_details?id=1,name=123,desc=1234. However the form just simply routes it into the default show/index methods in my controller. Anyway to route it directly to save_details method? Doing the below simply returns the error that says save_details does not exist as an id. Also editted my routes
new routes.rb
get '/rooms/save_details/:id/:name/:desc' => 'rooms#save_details', :as => 'save_details'
index.html.erb
<form action="rooms/save_details" method="get">
....
</form>
Looks like you're trying to save a form, this probably shouldn't be a get
resources :rooms do
post :save_details, on: :member
end
You're missing the :id parameter on your route helper. You need to do:
<%= form_for(#room, url: save_details_room_path(id: #room.id)) do |f| %>
And as Asthmatic suggested, that will have to be a :post route if a form is being submitted to it.
It appears you're using jQuery to fill in the room id, so you may have to skip the Rails form helper in favor of a plain HTML form. In that case you'll have to build and add the action attribute after you have the room id.
Finally solved it by using a normal HTML form and adding the following in routes.rb
get '/rooms/save_details/:id/:name/:desc' => 'rooms#save_details', :as => 'save_details'
resources :rooms do
get 'save_details', on: :collection
end

Rails button_to with image and actions

I want to show button with image.
I have this code
<%= image_submit_tag "down.png", controller: "posts", action: "votedown", post_id: post.id, topic_id: post.topic_id, class: "xta" %>
Its visible properly but not calling action "votedown"
In my routes I have
post '/votedown', to: 'posts#votedown
Please also suggest if there is any other way to call the method votedown with params and image "down.png"
image_submit_tag must be used in conjunction with a form - it works just a normal html <input type="submit"> button.
You might also want to change your route definition into something more restful:
patch '/posts/:id/votedown' => "posts#votedown", as: 'votedown_post'
This makes it more apparent that this route acts on a post - and we use the PATCH method since we are changing a resource instead of creating a new resource.
Armed with our new route we can simply create a form:
<%= form_for(#post, url: votedown_post_path(#post) ) do |f| %>
<%= image_submit_tag "down.png", class: "xta" %>
<% end %>
Note that you do not need to add an input for the post id since it will be available as params[:id].
Another way to do this would be to use Rails unobstructive javascript driver to create a link or button which sends a PATCH request to '/posts/:id/votedown'.
<%= link_to image_tag("down.png", class: "xta"), votedown_post_path(#post), method: :patch %>

Rails Call Custom Controller Action from Custom Form

In a Rails project, I have the following controller action for the controller exchanges.rb:
def update_ordid
# Get the active exchange
#exchange = Exchange.find(params[:id])
# Decide which order ID field to update
active_order_field = params[:ordfld]
# Save the order ID
order_id = params[:ordid]
if active_order_field == 1 then
#exchange.order_id_1 = order_id
else
#exchange.order_id_2 = order_id
end
#active_exchange.save
respond_with(#exchange)
end
I've set up a route to this controller action:
resources :exchanges do
collection do
get 'update_ordid'
end
end
I want to call this action that accepts an order ID from a form on an exchanges show.html.erb page. I need to pass three values:
The ID of the current exchange, such as the integer in this example URL localhost:3000/exchanges/2 (This is the page the form is on)
The order ID as input from a text-field
Which of the two possible exchange fields the action should update
Next I need to create a custom form which will pass these values as parameters to the action. I haven't been able to find a good tutorial on how to do this yet, but my first thought was to set up the following:
<%= form_for(#exchange) do |f| %>
<div class="field">
<%= f.label :ordid, "Order ID" %><br>
<%= f.text_field :ordid, class: "form-control" %>
</div>
<% if #isrequestor == true %>
<%f.hidden_field :ordfld, :value => "1" %>
<% else %>
<%f.hidden_field :ordfld, :value => "2" %>
<% end %>
<div class="actions">
<%= f.submit "Submit", class: "btn btn-primary" %>
</div>
<% end %>
This gives me a NoMethodError stating the method 'ordid' is undefined. I'm guessing I need to modify the first line of code to associate the form with the custom action I've set up, but have no idea how to do so properly.
Yah, I got your point. So you wanted the following thing:
You wrote an custom action
You wanted to submit a form that action
You have registered your action in the router.
So let me answer the following solutions and find some mistakes you made in your code.
# in route.rb
resources :exchanges do
patch :update_ordid, on: :member # this is the best practice I would say,
#when you are trying to modify an existing record. So this action will only
#be reached with patch http methods
# on :member action an parameter id is required.
end
now if you generate your routes by running:
bundle exec rake routes
you will see a path like:
update_ordid_exchange /exchange/:id/update_ordid # :id parameter for exchange record
in your form set the url:
<%= form_for(#exchange, url: update_ordid_exchange_path) do |f| %>
or
<%= form_for(#exchange, url: url_for(controller: :exchange, action: update_ordid)) do |f| %>
Now then you will this form can submit this values within the parameter in your desire field.
So let me summarize things up here:
1. Setup your route properly
2. Check the url based on your route by generating rake routes command as shown above
3. Set the proper url and check if http method is correctly define in your form helper. For member actions, form helper by default use patch as http method. you just have to set the url.
Hope you understand my flow.

Rails Routing and link_to

It's a little late here so maybe this a trivial question where I'm missing something simple. But when I click a button (with link_to) I created the following gets appended to my URL:
%23<ActionView::Helpers::FormBuilder:0x3ef1fd8>
Why is this, and how can I prevent this? Again, I apologize if this is a shallow question. I can post more information regarding routes and whatnot if that is needed.
Thanks!
Edit: More information as requested.
View:
<%= link_to "Index", welcome_path(f), :class => 'button' %>
with f being part of a form_for loop. I think I'm passing the wrong parameter but I'm unsure.
Relevant Route:
get "index" => 'welcome#show', :as => 'index'
Update:
Thanks for the help everyone. I ended up getting it working by pluralizing my controller (I don't know why I didn't have that before) and utilizing welcome_url instead. That seemed to do the trick.
Check out the very first example and paragraph in the Rails API docs for ActionView::Helpers::FormBuilder:
<%= form_for #person do |f| %>
Name: <%= f.text_field :name %>
Admin: <%= f.check_box :admin %>
<% end %>
What this is saying is that f represents an instantiated FormBuilder object that you are passing to the welcome_path method in your link_to helper.
Typically, you would not mix #index and #show in your routes. Depending on what you want to use the WelcomesController for, you might actually want to route your root_path to welcome_index:
get "welcome/show" => 'welcome#show', :as => 'welcome'
root 'welcome#index'
You should run: $ rake routes in the terminal to get an idea of path view helpers that you can use in your app.
Maybe you're trying to send users to a personalized welcome page. You could have something like this for your corresponding link_to helpers would look best like this:
<%= link_to "Show", welcome_path(#user.id), :class => 'button %>
<%= link_to "Index", root_path, :class => 'button' %>

Routing a form/create object post request in rails--problems with the form and routing request

I'm pretty new to rails so sorry if this is poorly worded... for a course, I'm creating an app that lets you add (post) new instances of classes called Planets and Moons. Moon is supposed to be a child of Planet. Right now I can create both in separate database tables, using three route requests:
get "planets" => "planets#index"
get "planets/new" => "planets#new"
post "/planets" => "planets#create"
(This create a form page to register new planets. Substitute "moons" and the moon class works the same, including create, from it's own form page.)
I have a fourth route for a planets show-by-id page
get "planets/:id" => "planets#show"
On this planets id show page, I want to create an "Add a moon" form that takes the param ID for the planet, lets the user enter a moon name, and sends the post request to create the new instance.
I don't think I know enough about forms and routing.
My form for the new moons is
<%= form_for #moon, url: "/planets/:id" do |f| %>
<p><strong>New Moon Name:</strong></p>
<p>Name: <%= f.text_field :name %></p>
<% Planet.find(params[:id]: :planet_id %>
<p><%= f.submit "Create!" %></p>
<% end %>
The three "moon" routes I have:
1) get "moons" => "moons#index"
2) get "moons/new" => "moons#new" (goes to a form I was using to test, I don't know if I need this)
3) post "/planets/:id" => "moons#create" (where I think the problem is)
I think I may need to use interpolation to get the planet ID from the params into the moon posting form so help there is great, but I'm more concerned with getting past the line:
<%= form_for #moon, url: "/planets/:id" do |f| %>
I get error: "First argument in form cannot contain nil or be empty"
This is what I have defined in the moons controller...
def new
#moon = Moon.new
end
def create
moon_attributes = params[:moon]
Moon.create({
name: moon_attributes[:name],
planet_id: moon_attributes[:planet_id]
})
end
I hope this question makes sense. Thanks in advance!
To give you some perspective, here's what you need to do:
#config/routes.rb
resources :planets, only: [:index, :new, :create, :show] do
resources :moons, only: [:create] #-> planets/:id/moons
end
This uses the resourceful routing structure in Rails, giving you the paths you have already anyway.
In terms of your form, you'd be best doing this:
#app/views/planets/show.html.erb
<%= form_for #moon do |f| #-> should route to moons_controller#create %>
<p><strong>New Moon Name:</strong></p>
<p>Name: <%= f.text_field :name %></p>
<p><%= f.submit "Create!" %></p>
<% end %>
#app/controllers/moons_controller.rb
class MoonsController < ActiveRecord::Base
def create
moon = Moon.new(moon_params)
moon.save
redirect_to planets_show_path(planet)
end
private
def moon_params
params.require(:moon).permit(:name).merge(planet_id: params[:planet_id])
end
end

Resources