When I click submit button in my form, create action is supposed to work but it is rather processed by new action
It is really weird that it works in the first case and not in the second.
Try this,
<%= simple_form_for @task, url: tasks_path, method: :post, html: {class: 'form-horizontal'}, wrapper: :horizontal_input_group do |f| %>
this will force the form to submit to tasks_path with post method which goes to the create action. Let me know if it works
Also, this is your create method
def create
@task = current_user.client_relationships.build(task_params)
if @task.save
flash[:success] = "Micropost created!"
redirect_to @current_user
else
render 'new'
end
end
A couple of issues.
1) redirect_to @current_user does not mean anything, right ? should be like user_path(@current_user)
2) you should always do redirect_to and return so that the code block after redirection will not be called. In your case, its ok since the rest is in a else block
3) It could be that task.save fails and new is rendered. use a debugger and check if comes to first line of create
Submit same form to different actions
In this case creating a Cat
and updating a Dog
were related enough that it makes sense to handle both in the CatsController
with a case statement and use a :name
attribute on on the submit
button.
For example:
app/views/cats/new.html.erb:
<%= form_tag(cats_path, multipart: true, role: "form") do %>
<%= button_tag 'Cat', name: 'route_to[cat]'%>
<%= button_tag 'Dog', name: 'route_to[dog]' %>
<% end %>
app/controllers/cats_controller.rb:
def create
case route_to params
when :cat
# create a cat
when :dog
# update a dog
end
end
.
.
.
private
def route_to params
params[:route_to].keys.first.to_sym
end
Submitting a form with a param to new controller action
In Rails you don't create resources by posting to the new
route- you post to the collection route eg. /books
. The new action is just used to create a page with a form on it.
Its still really puzzling why new_book_path
would return /bookd/new
but the error is actually correct. new_book_path
responds to GET - not POST. This is explained in Rails Routing from the Outside.
If you actually just use:
table.table.table-striped
thead
tr
th Name
tbody
- @books.each do |book|
tr
td = book.name
= simple_form_for(@book || Book.new) do |f|
.form-inputs
= f.input :name # book_name is a typo?
It will correctly create a form with action="/books" method="POST"
.
I have no idea what your trying to do with this mess:
= form_with url: new_book_path do |f|
.form-inputs
= f.label 'Add Book'
= f.text_field :book_name
.form-actions
= f.submit
= simple_form_for(@book) do |f|
.form-inputs
= f.input :book_name
But none of the HTML specifications allow nested <form>
elements and the results can be wildly unpredictable. For example a submit button may submit the inner form or the outer form.
How to get form submit button to do update action as opposed to create action
Generally you don't need template for edit form if nothing special.
Just use create form and use form_for @instance
.
form_for
will judge the instance and arrange form path automatically. If the instance is not persisted, it will point to #create
. If the instance is a persisted object in db, it will point to #udpate
automatically.
multiple controllers in one view (ruby on rails MVC)
Technically, this terminology is somewhat confusing. By default each method in a controller corresponds to a similarly-named view file, so it may be better to word the question as "Is it good practice to render a view that is not the default view?" And the answer is, of course, it depends. It is a technique commonly used to DRY up controller code and if there are advantages to be gained by it, in your application, I would certainly use it. In fact, the controller code generated by the default resource scaffolding in Rails uses it in the
create
andupdate
methods. I think you could make the argument that anything in Rails core is, if not a best-practice, at least within the limits of sanity.With that being said, there may be opportunities for improvement. A common way to handle the same thing would be to route your create and update requests to the same controller action and use the same controller view. If that is not feasible, at least be assured that you will not need to redefine the variables. From the official documentation:
Using render with :action is a frequent source of confusion for Rails
newcomers. The specified action is used to determine which view to
render, but Rails does not run any of the code for that action in the
controller. Any instance variables that you require in the view must
be set up in the current action before calling render.
- You shouldn't need to do that... Not in this situation, or any other one that I can think of. Any time you see something super hackey like that in Rails is a sign that something probably isn't quite right, and that there are probably better ways to handle the same thing.
Bonus: If you need to go somewhere that already is in charge of setting itself up, and you don't need access to any of the in scope variables, a redirect is probably a better choice. That way, you don't need to re-describe your controller logic in multiple places. Here is an example from your posted code:
# inefficient and not DRY
@user = User.find(current_user)
@microposts = @user.microposts.paginate(page: params[:page])
render 'users/show'
# does the same thing as above (in this case)
redirect_to users_path
In Rails when a resource create action fails and calls render :new, why must the URL change to the resource's index url?
It actually is sending you to the create path. It's in the create
action, the path for which is /books
, using HTTP method POST. This looks the same as the index path /books
, but the index path is using HTTP method GET. The rails routing code takes the method into account when determining which action to call. After validation fails, you're still in the create action, but you're rendering the new
view. It's a bit confusing, but a line like render :new
doesn't actually invoke the new action at all; it's still running the create action and it tells Rails to render the new view.
RoR: button click action call
In light of the other answers not working, here is what I propose:
#config/routes.rb
resources :logins, only: [:index, :create] do
collection do
get :buttons
end
end
#view
<%= link_to "Submit", logins_buttons_path # -> whatever the path helper is %>
I have used link_to
because this answer recommends button_to
for POST
requests. This should work for you, but it's non-conventional, so you'll be best describing how you want it it work
Update
I am glad this worked for you
Several things which probably contributed to its functionality:
- Conventional routes
- Using
link_to
When using routing
in Rails, it's basically middleware which defines how your app will "catch" incoming requests. When you browse to domain.com/route
, Rails takes the /route
& the HTTP verb
part of the URL & loads the corresponding controller / action
to help it load up.
When defining your routes, you therefore need to be extremely careful about which routes
you define, and how you define them. The best way is to use Rails conventions (which essentially means using inbuilt helpers) such as resources :controller
--
We also used the link_to
in place of button_to
button_to
creates a small form on your page, which then sends a request to your assigned route. This form is typically POST
, but can be assigned GET
. In light of your new comment, you'll probably want to read up on the button_to
documentation to get it formatted correctly
Related Topics
Ruby Timeouts and System Commands
Use of Caret Symbol (^) in Ruby
Jekyll Serve Dependency Error - Could Not Open 'Lib Curl'
How to Send Message Using Gmail API with Ruby Google API Client
Interpretation as a Local Variable Overrides Method Name
Combining Multiple Named Scopes with Or
How to Dump an Object's Fields to the Console
Rails Select Drop Down for States
How to Run a Ruby File in a Rails Environment
Rspec Failing Error: Expected False to Respond to 'False'
Ruby Method That Returns Itself
Rails Article Helper - "A" or "An"
How to Decode Rijndael in Ruby (Encoded in Vb.Net)
Building Ruby with Rbenv and Ruby-Build Fails with Undefined Symbol: Sslv2_Method
What Are <-- Ruby Strings Called? and How to Insert Variables in Them