triggering post request, a get request is triggered rails - ruby-on-rails

I will be very thankful if anyone can help me out in this.
I have a route that is a post request and I am using it as a post request in my views but when I hit the route it shows get request in the browser.
This is what I have in routes:
resources :candidate_folders, only: [:create, :show, :update, :destroy] do
member do
post '/move_job_slot/:folder/:job_slot', to: 'candidate_folders#move_job_slot', as: :move_job_slot
end
end
This is how I am using it in my views
<%= link_to link, method: :post, class:'is-text' do %>
<div class="rounded border hover:bg-gray-100 py-2 px-4">
<div class="flex justify-between items-center space-x-1">
<p class="truncate">
<%= icon 'fa', 'folder' %>
<%= folder.name %>
</p>
<p class="text-sm text-gray-500 whitespace-nowrap">
<%= folder.n_job_slots %>
</p>
</div>
</div>
<% end %>

Link_to by default triggers a get request. In order to make a post for rails 6 or less you can use method: :post however for rails 7 and above method: "post" as well as remote: true option with link_to is deprecated since rails 7. So now with link_to you would do something similar data: { turbo_method: "post" } to achieve the same behaviour of a non-get request.
https://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to
https://guides.rubyonrails.org/working_with_javascript_in_rails.html#replacements-for-rails-ujs-functionality

Related

How to delete an individual newsletter signup inside a .each loop

I am trying to implement a delete button for each newsletter signup on my Users Show view in an admin section.
What I'm trying now:
<% #news_subs&.each do |news| %>
<div class="vert-flip bot-drop">
<div class="wellington bot-drop sub-well flip-card-inner">
<div class="flip-card-front">
<p class="align-left left hype"><%= news.name %></p>
<p class="align-right right"><%= news.verified %></p>
<div style="clear: both;"></div>
</div>
<div class="flip-card-back">
<p class="newsletter-email"><%= news.email %></p>
<%= link_to "Remove", news, method: :delete,
data: { confirm: "Are you sure you want to..." },
class: "btn btn-xs btn-danger newsletter-remove" %>
</div>
</div>
</div>
<% end %>
But I am getting the following error:
Routing Error
No route matches [DELETE] "/newsletter.2"
I have tried using: <%= link_to "Remove", Newsletter.find(params[:id]), method: :delete, but that just throws the same error as well.
How can I delete the individual news_sub and not navigate away from the page?
Using Ruby 3 and Rails 6.1
Update:
Rails Routes:
newsletter_index GET /newsletter(.:format) newsletter#index
POST /newsletter(.:format) newsletter#create
new_newsletter GET /newsletter/new(.:format) newsletter#new
edit_newsletter GET /newsletter/:id/edit(.:format) newsletter#edit
GET /newsletter/:id(.:format) newsletter#show
PATCH /newsletter/:id(.:format) newsletter#update
PUT /newsletter/:id(.:format) newsletter#update
DELETE /newsletter/:id(.:format) newsletter#destroy
edit_news_verification GET /news_verification/:id/edit(.:format) news_verification#edit
Routes.rb:
get 'newsletter', to: 'newsletter#newsWelcome', as: 'newsWelcome'
post 'newsletter', to: 'newsletter#create'
...
resources :newsletter
resources :news_verification, only: [:edit]
You can fix this by specifying the route rather than just passing the object to your link_to method. Instead of passing news specify the path you need, eg news_sub_path(news).
This should work:
<%= link_to "Remove", news_sub_path(news), method: :delete,
data: { confirm: "Are you sure you want to..." },
class: "btn btn-xs btn-danger newsletter-remove" %>

Rails 5. How to submit from the form_tag to custom action?

I'm a real newbie at Ruby and Rails, and I've been looking for the solution for two days. I need to submit data from form_tag to action 'create' in my controller to add new entries to database, but looks like I'm doing something terribly wrong, because absolutely nothing happens, and it seems that form_tag doesn't even redirect to needed action.
Here's the page code:
<h1>Todos</h1>
<% #projects.each do |project| %>
<tr>
<h2><%= project.title %></h2>
<% project.todos.each do |todo| %>
<ul style="list-style-type:disc">
<li><%= todo.text %></li>
</ul>
<% end %>
</tr>
<% end %>
<%= form_tag({controller: "mega", action: "create"}, method: "get", remote: true) do %>
<h2>New todo</h2>
<p>
<%= text_field_tag 'text' %>
</p>
<p>
<%= select_tag 'title', options_from_collection_for_select(#projects, 'id', 'title') %>
</p>
<p>
<%= link_to 'CANCEL' %>
<%= link_to 'OK', "", :onclick => "$('#form_id').submit()" %>
</p>
<% end %>
And the controller:
class MegaController < ApplicationController
def index
#projects = Project.all
#todos = Todo.all
end
def update
end
def create
#newTodo = Todo.create(text: params[:text])
#newProject = Project.find_by(title: params[:title])
#newProject.todos << #todo
#newTodo.save
end
end
My routes file. I seriously don't know how it works:
Rails.application.routes.draw do
get 'mega/index'
root 'mega#index'
get 'mega/update'
post 'mega/create'
resources :todos
resources :projects
end
You create resources with a POST request. Never GET.
GET requests should be idempotent - they should not update or alter resources on the server. One very important reason is that they are stored in the browser's history, so pressing the back button will cause unintended consequences for the user.
In Rails flavor MVC instead of tacking the action name on the path of the route you use the HTTP verb to create routes to the correct action:
GET /things things#index
POST /things things#create
I'm not going to attempt to salvage your code (it's deeply flawed) and instead show you how you would solve this the rails way as it is much simpler:
<%= form_for(Todo.new) do |f| %>
<h2>New todo</h2>
<%= f.text_field :text %>
<%= f.collection_select(:project_id, #projects, :id, :title, prompt: true) %>
<%= f.submit %>
<% end %>
This would submit to todos#create - if you want to route it to an unconventional action you can use the url option:
<%= form_for(Todo.new, url: polymorphic_path(controller: 'foo', action: 'bar')) do |f| %>
It's best to learn the rules before you break them.

No route matches {:action=>"upvote", :controller=>"kindergartens", :id=>nil} missing required keys: [:id]

I'm fresh at Rails and I've seem similar problems, but I can't solve mine.
My routes:
resources :kindergartens do
member do
put"like",to:"kindergartens#upvote"
end
member do
post :join
post :quit
end
My model:
acts_as_votable
My controller:
def upvote
#kindergarten = Kindergarten.find(params[:id])
#kindergarten.upvote_by current_user
redirect_to :back
end
My index.html:
<%= link_to like_kindergarten_path(#kindergarten), method: :put do %>
<div class="pi-thumbs-up">
<i class="fa fa-thumbs-up fa-2x" , style="color:#ff5722;"></i>
<%= kindergarten.get_upvotes.size %>
</div>
<% end %>
There is no error in the show.html.erb. But cannot work in the
index.html.erb.
And I'm getting the same error:
ActionController::UrlGenerationError in Kindergartens#index
Showing /Users/liudezheng/Dropbox/未命名文件夹/Lyn-add-
votes/app/views/kindergartens/index.html.erb where line #66 raised:
No route matches {:action=>"upvote", :controller=>"kindergartens",
:id=>nil} missing required keys: [:id]
Since it is index action, I assume you must be looping `#kindergartens,
so, according to the line <%= kindergarten.get_upvotes.size %> the parameter of the loop is kindergarten not #kindergarten
So, it should be
<%= link_to like_kindergarten_path(kindergarten), method: :put do %>
<div class="pi-thumbs-up">
<i class="fa fa-thumbs-up fa-2x" , style="color:#ff5722;"></i>
<%= kindergarten.get_upvotes.size %>
</div>
<% end %>
PS: Share your index action, and the complete index.html to get the more relavant answers.
#kindergarten inside index.html.erb is nil.
To solve this you probably want to do one of the following:
# kindergarten_controller.rb
def index
#kindergartens = Kindergarten.all
end
Your HTML:
# kindergartens/index.html.erb
<%= #kindergartens.each do |kindergarten|
<%= link_to like_kindergarten_path(kindergarten), method: :put do %>
<div class="pi-thumbs-up">
<i class="fa fa-thumbs-up fa-2x" , style="color:#ff5722;"></i>
<%= kindergarten.get_upvotes.size %>
</div>
<% end %>
I hope that helps.

No route matches [GET] "/recipes/1/like" I want a POST request

I've never encountered this problem before. I'm getting this error.
No route matches [GET] "/recipes/1/like"
Here is my routes.rb:
Rails.application.routes.draw do
root 'pages#home'
get '/home', to: "pages#home"
resources :recipes do
member do
post 'like'
end
end
end
Here is my recipes_controller:
def like
#recipe = Recipe.create(params[:id])
Like.create(like: params[:like], chef: Chef.first, recipe: #recipe)
#flash message
flash[:success] = "Your selection was sucessful"
redirect_to :back
end
Here is my html.erb file:
<%= render 'shared/page_title', title: #recipe.name.titleize %>
<div class= "row">
<div class="col-md-4 pull-right center">
<%= gravator_for #recipe.chef, size: 200 %>
<p>
<h5>Brought to you by: <%= #recipe.chef.chefname.capitalize %></h5>
</p>
</div>
<div class= "col-xs-8 col-md-8">
<%= link_to "Edit this Recipe", edit_recipe_path(#recipe), class: "btn btn-success pull-right" %>
<h3><%= #recipe.summary.capitalize %></h3>
<div class="show_recipe">
<%= image_tag(#recipe.picture.url, size: "300x200", class: "recipe-image") if #recipe.picture? %>
</div>
<div class ="well recipe-description">
<p>
<strong> Steps:</strong>
</p>
<%= simple_format(#recipe.description) %>
<div class="pull-right">
<%= link_to like_recipe_path(#recipe, like: true), method: :post do %>
<i class="glyphicon glyphicon-thumbs-up"></i>
<% end %> &nbsp&nbsp&nbsp&nbsp
<%= link_to like_recipe_path(#recipe, like: false), :method => :post do %>
<i class="glyphicon glyphicon-thumbs-down"></i>
<% end %>
</div>
</div>
</div>
</div>
<h5><%= link_to "Return to Recipes Listings", recipes_path, class: "btn btn-warning btn-small" %></h5>
I've explicitly added the HTTP POST request to my html.erb file
%= link_to like_recipe_path(#recipe, like: true), method: :post do %>
but rails is complaining that there is no GET route request, which I never created in my routes because I need a POST request for this particular section of the web app.
Rake routes:
Prefix Verb URI Pattern Controller#Action
root GET / pages#home
home GET /home(.:format) pages#home
like_recipe POST /recipes/:id/like(.:format) recipes#like
recipes GET /recipes(.:format) recipes#index
POST /recipes(.:format) recipes#create
new_recipe GET /recipes/new(.:format) recipes#new
edit_recipe GET /recipes/:id/edit(.:format) recipes#edit
recipe GET /recipes/:id(.:format) recipes#show
PATCH /recipes/:id(.:format) recipes#update
PUT /recipes/:id(.:format) recipes#update
DELETE /recipes/:id(.:format) recipes#destroy
I am honestly lost. It seems that everything is in its right place.
Rails version:
Rails 4.2.5
I've defined the action, created the like model, nested the route under recipes, and explicitly requested for a post HTTP request in the html.erb page.
Any ideas would be great!
Cheers!
Here's the relevant code from my working project with a similar arrangement.
# /views/events/splits.html.erb:
<%= link_to "Add",
associate_splits_event_path(id: #event.id, split_ids: [split.id]),
:method => :put,
:class => 'btn btn-xs btn-success' %>
# routes.rb
resources :events do
member { put :associate_splits }
end
If it's helpful to see it in context, feel free to poke around the repo. Here's a link to the view: https://github.com/SplitTime/OpenSplitTime/blob/master/app/views/events/splits.html.erb
While rails link_to does allow links to make requests with a method other than GET, it is not the normal behavior of links and relies on Javascript to make a form which gets submitted behind the scenes. Rails uses jquery-ujs for this, so make sure you haven't disabled it.
That said, making POST requests is normal behavior for forms, so you could also try using button_to instead, and simply styling the button to look like a link if necessary.
<%= button_to "Like", like_recipe_path(#recipe), method: :delete, like: true %>
Additional Info:
https://github.com/rails/jquery-ujs
http://apidock.com/rails/ActionView/Helpers/UrlHelper/button_to
Try with
<%= link_to "LIKE", like_recipe_path(#recipe) , method: :post %>
Other option:
<%= link_to '<i class="glyphicon glyphicon-thumbs-up"></i>'.html_safe , like_recipe_path(#recipe , like: 'value' ) , method: :post %>
You need to add a GET route:
resources :recipes do
member do
get 'like'
post 'like'
end
end

param is missing or the value is empty: plant

I have added a custom action in my controller called transplant. I simply want to render a dropdown form to select where to be located based on the 'tray_id'
my routes look like this:
resources :plants do
member do
get 'transplant'
end
resources :plantdats, :plant_cycles, :tasks
end
My controller looks like this:
before_action :set_plant, only: [:show, :edit, :update, :destroy, :transplant]
def transplant
if #plant.update(plant_params)
redirect_to #plant
flash[:success] = "Transplanted successfully"
end
end
def set_plant
#plant = Plant.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def plant_params
params.require(:plant).permit(:title, :notes, :category_id, :tray_id, images_files: [])
end
Here is my button calling the action
<%= link_to 'TRANSPLANT', transplant_plant_path(#plant), class: "btn btn-raised btn-info hoverable" %>
Here is my transplant page _transplant.html.erb
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="jumbotron">
<%= form_for(#plant, html: {class: 'form-horizontal'}) do |f| %>
<% if #plant.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#plant.errors.count, "error") %> prohibited this grow from being saved:</h2>
<ul>
<% #plant.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.label 'NAME' %>
<%= f.hidden_field :tray_id, value: params[:tray_id] %>
<% if params[:tray_id].nil? %>
<%= f.collection_select(:tray_id, Tray.all, :id, :title) %></br></br>
<% end %>
<%= f.submit class: 'btn btn-raised hoverable btn-success' %>
<% end %>
</div>
</div>
</div>
EDIT
After implementing the route to post 'transplant
and changing my link code to
<%= link_to "TRANSPLANT", transplant_plant_path(#plant, tray_id: #plant.tray_id), method: "post", class: "btn btn-raised hoverable" %>
I still get the same error. It points right to the plant_params code in my controller.
These are the params that are being passed:
{"_method"=>"post",
"authenticity_token"=>"fhSKt2DpgTwt1J4HsoBqYFSs0B9+pgSvDDxrS/u6yo4c3gvSxYlrrFDmhbPXq+cMho/eTHY+194WZ8zpcb1txA==",
"id"=>"1",
"format"=>"1"}
Im simply trying to update the :tray_id
Ive been at this all day, can anyone help with the error that Im getting?
You should probably provide your code for your transplant action and view. Based on what you provided, it seems like you're trying to build a link, which changes the tray of a plant when clicked. If that's the case, transplant should probably be a POST route instead of GET. Also, you probably want to provide the tray_id in your post link like this:
<%= link_to "TRANSPLANT", transplant_plant_path(#plant, tray_id: {{your id}}), method: "post", class: "..." %>
Then you can get tray_id in your transplant through params[:tray_id] and re-associate your plant and tray
Essentially what I was trying to do was not easily done and my approach needed to change. I simply rendered the transplant form in my view and it works fine now. Thanks again :)
Check your routes you just have defined get route and your request is post after the form submission

Resources