Destroy action in controller doesn't work - ruby-on-rails

I can't manage to get my destroy action in my controller to work. I've read that you have to include default javascript libraries to delete, but I've done that (at least I think I have), and it still doesn't work. Background on my app: articles are "recipes", so my controller is called recipes_controller. Here's the code from my recipes_controller:
class RecipesController < ApplicationController
before_action :authenticate, except: [:index, :show]
before_action :set_recipe, only: [:show, :edit, :update, :destroy]
# GET /recipes
# GET /recipes.json
def index
#recipes = Recipe.all
end
# GET /recipes/1
# GET /recipes/1.json
def show
end
# DELETE /recipes/1
# DELETE /recipes/1.json
def destroy
#recipe.destroy
respond_to do |format|
format.html { redirect_to recipes_url, notice: 'Recipe was
successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_recipe
#recipe = Recipe.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def recipe_params
params.require(:recipe).permit(:title, :body, :published_at, :category_ids => [])
end
end
Then, here's the code for my application.html.erb file, where I thought i had included the default javascript libraries:
<html>
<head>
<title>inherentlydope</title>
<%= stylesheet_link_tag :all %>
<%= javascript_include_tag :defaults %>d
<%= csrf_meta_tag %>
</head>
<body>
<%= content_tag :p, notice, :class => 'notice' if notice.present? %>
<%= content_tag :p, alert, :class => 'alert' if alert.present? %>
<%= yield %>
</body>
</html>
Then, here's my routes.rb file:
Rails.application.routes.draw do
root to: "recipes#index"
#resources :comments
resources :recipes do
resources :comments
end
resources :users
resource :session, only: [:new, :create, :destroy] #always deal with session, not sessionS
get '/login' => "sessions#new",as: "login"
get '/logout' => "sessions#destroy", as: "logout"
end

Related

Rails - Searching/showing available option when creating new instance of an object

I've got a one to many relationship with one movie per list entry, where a movie can be used in a list entry. My list_entries table has a movie_id and a list_id.
database schema
I've nested list_entries in lists so I can pass the list_id directly when creating a new instance.
Rails.application.routes.draw do
devise_for :users
root to: 'pages#home'
resources :movies, only: [:new, :index, :create, :show, :destroy, :edit, :update]
resources :users, only: [:show, :edit, :update]
resources :lists, only: [:new, :create, :show, :index, :destroy] do
resources :list_entries
end
end
Right now I can create and destroy list entries but I have to specify the movie id manually.
The UX I want to achieve is for the user to be able to search for movies from themy list_entries/new form but I don't even know where to begin.
The form as it is now:
<%= simple_form_for #list_entry, url: list_list_entries_path do |f| %>
<%= f.input :comment %>
<%= f.input :movie_id %>
<%= f.submit "Add", class: "btn devise-button" %>
<% end %>
My list entries controller:
class ListEntriesController < ApplicationController
before_action :find_list, only: [:index, :create, :show, :new, :destroy]
def new
#list_entry = ListEntry.new
end
def index
#list_entries = ListEntry.where(list: #list)
end
def show
#list_entry = ListEntry.find(params[:id])
end
def destroy
#list_entry = ListEntry.find(params[:id])
#list_entry.destroy
redirect_to list_list_entries_path
end
def create
#list_entry = ListEntry.new(entry_params)
#list_entry.list_id = params[:list_id]
if #list_entry.save
redirect_to list_list_entries_path
else
render 'new'
end
end
private
def find_list
#list = List.find(params[:list_id])
end
def entry_params
params.require(:list_entry).permit(:comment, :movie_id)
end
end
If you don't want to manually specify a movie_id in the form, you can use the simple_form_for association helper:
<%= f.input :comment %>
<%= f.association :movie %>
I believe it should be labeled based off of the movie title, but if not, you may have to specify a #to_label method in your Movie model.
Alternatively, you could query for the movies in your #new action and use them to do whatever you like in your view:
def new
#list_entry = ListEntry.new
#movies = Movie.all # or whatever query you think is relevant
end
The #collection_select documentation might be useful here:
https://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/collection_select

No route matches [GET] "/accounts.json"

I am attempting to provide a user with the ability to create a subdomain. When clicking Create Account, the system redirects from "accounts/new" to "accounts" and no subdomain is getting populated.
routes.rb
class SubdomainPresent
def self.matches?(request)
request.subdomain.present?
end
end
class SubdomainBlank
def self.matches?(request)
request.subdomain.blank?
end
end
Saasapp::Application.routes.draw do
constraints(SubdomainPresent) do
root 'projects#index', as: :subdomain_root
devise_for :users, controllers: { registrations: 'users/registrations' }
resources :users, only: :index
resources :projects, except: [:index, :show, :destroy]
end
constraints(SubdomainBlank) do
root 'visitors#new'
resources :accounts, only: [:new, :create]
end
end
accounts_controller.rb
class AccountsController < ApplicationController
skip_before_action :authenticate_user!, only: [:new, :create]
def new
#account = Account.new
end
def create
#account = Account.new(account_params)
if #account.valid?
Apartment::Database.create(#account.subdomain)
Apartment::Database.switch(#account.subdomain)
#account.save
redirect_to new_user_session_url(subdomain: #account.subdomain)
else
render action: 'new'
end
end
new.html.erb
<%= simple_form_for #account do |f| %>
<%= f.input :subdomain do %>
<div class="input-group">
<%= f.input_field :subdomain, class: 'form-control' %>
<span class="input-group-addon">.demo.dev</span>
</div>
<% end %>
<%= f.button :submit, class: 'btn-primary' %>
<% end %>
error in logs
Started GET "/accounts.json" for 127.0.0.1 at 2017-02-08 21:56:08 -0500
ActionController::RoutingError (No route matches [GET] "/accounts.json"):
This line:
resources :accounts, only: [:new, :create]
is telling Rails "only set up the new and create route for an account".
It basically says "do not set up an index route"
if you want an index route (ie that will show a list of all the accounts) then you need to update that line to eg:
resources :accounts, only: [:new, :create, :index]
Add :index route to line:
resources :accounts, only: [:new, :create]
In AccountsController create index action and handle
render json: YourObject

param is missing or the value is empty when trying to update using active resource

I'm making one simple rails application with simple forms for crud operations and one rails api that will have models and do all crud operations with data from rails application. In application i'm using ActiveResource. Currently i'm having some problems with update...Everything else works only when i update it breaks and i don't know why, plz help.
api/postcontroler
class API::PostsController < ApplicationController
before_action :set_post, only: [:show, :update, :destroy]
# GET /posts
# GET /posts.json
def index
#posts = Post.all
render json: #posts
end
# GET /posts/1
# GET /posts/1.json
def show
render json: #post
end
# POST /posts
# POST /posts.json
def create
#post = Post.new(:title => params[:title], :content => params[:content])
if #post.save
render json: #post, status: :created, location: #post
else
render json: #post.errors, status: :unprocessable_entity
end
end
# PATCH/PUT /posts/1
# PATCH/PUT /posts/1.json
def update
if #post.update_attributes(post_params)
render json: #post
else
render json: #post.errors, status: :unprocessable_entity
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
#post.destroy
head :no_content
end
private
def set_post
#post = Post.find(params[:id])
end
def post_params
params.require(:post).permit(:title, :id, :content)
end
end
application/postcontroler
class PostsController < ApplicationController
before_action :set_post, only: [:show, :update, :edit, :destroy]
def index
#posts = Post.all
end
def new
#post = Post.new(:title => "", :content => "")
end
def create
#post = Post.new(post_params)
if #post.save
redirect_to post_path(#post)
else
render "new"
end
end
def show
#comments = Comment.find(:all, :params => {:post_id => params[:id]})
end
def edit
end
def update
#post.title = params[:title]
#post.content = params[:content]
if #post.save
redirect_to post_path(#post)
else
render "edit"
end
end
def destroy
#post.destroy
redirect_to :action => 'index'
end
private
def post_params
params.require("post").permit(:title, :content)
end
def set_post
#post = Post.find(params[:id])
end
end
application/edit.html.erb
<%= form_for(#post, :url=>{:action=>'update'}) do |f| %>
<%= f.label :title %><br>
<%= f.text_field :title %><br>
<%= f.label :content %><br>
<%= f.text_area :content %><br>
<%= f.submit %>
<% end %>
application routes
resources :posts do
resources :comments
end
api routes
namespace :api, :defaults => {:format => :json} do
resources :posts, except: [:new, :edit] do
resources :comments, except: [:new, :edit]
end
end
application active resource post model
class Post < ActiveResource::Base
self.site = "http://localhost:3001/api"
end
I start application at port 3000 and api at 3001,when i try to update this happens
on application
application
and this on api
api
What's the problem?
You have the formats mixed up for your two controllers.
api/postcontroller is expecting non-nested parameters, and application/postcontroller is expecting nested parameters, but you are passing them in the opposite way. So the api version fails, because the require(:post) fails, and the application version fails, because the data you are looking for is in `params[:post][:title], not params[:title].
Try swapping the bodies of the two update methods (with the appropriate modification, you don't want the application serving Json etc).

Routing Error No Route Matches (correct route)

I'm in the process of building an edit form. I have completed the form and it renders as it should. When I go to submit the update to the form I get a no route error. The path to my edit page is for example '/topics/1/bookmarks/1/edit'. This page loads perfectly fine. That page contains a partial of the form that will be used to edit the record. When I select the submit button however it re-routes to '/topics/1/bookmarks/1' and gives me the following:
Routing Error
No route matches [PATCH] "/topics/1/bookmarks/1"
Below are the files that should be of importance let me know if there is something I did not share. That would be important to view.
bookmarks_controller.rb
def edit
#topic = Topic.find(params[:topic_id])
#bookmark = Bookmark.find(params[:id])
end
def update
#topic = Topic.find(params[:topic_id])
#bookmark = Bookmark.find(params[:id])
if #bookmark.update_attributes(params.require(:bookmark).permit(:url, :topic_id, :description))
flash[:notice] = "Bookmark was updated"
redirect_to [#topic, #bookmark]
else
flash[:error] = "There was an error saving the Bookmark. Please try again."
render :edit
end
end
config/routes.rb
resources :topics do
resources :bookmarks, only: [:show, :new, :edit]
end
bookmarks/_form.html.erb
<%= form_for [topic, bookmark] do |f| %>
<%= f.label :description %>
<%= f.text_field :description %>
<%= f.label :url %>
<%= f.text_field :url %>
<%= f.submit %>
<% end %>
bookmarks/edit.html.erb
<%= render partial: 'form', locals: {topic: #topic, bookmark: #bookmark} %>
You don't have an update route, which is what actually updates the database. Just change
resources :bookmarks, only: [:show, :new, :edit]
to
resources :bookmarks, only: [:show, :new, :edit, :update]
OR better yet,
resources :bookmarks, except: [:index, :create, :destroy]
If you have a new action, then you should want a create action too. So, finally:
resources :bookmarks, except: [:index, :destroy]

Model won't update on submission

Im getting this weird error when i want to update my model (model name carts).
Error : The action 'update' could not be found for CartsController
this is my carts_controller.rb :
class CartsController < ApplicationController
include CartForcable
before_action :scoped_cart, only: [:show, :update]
def show
end
private
def scoped_cart
force_cart! lambda {|r| r.includes(:entries => {:sign => [:dimensions, :substrates]})}
end
def update
#cart = #cart.find(params[:id])
if #cart.update_attributes(cart_params)
flash[:notice] = translate 'flash.notice'
else
flash[:error] = translate 'flash.error'
end
support_ajax_flashes!
respond_to do |format|
format.html # renders view
format.json { render json: #entry }
end
end
end
and these are my routes.rb :
resources :categories, only: [:index] do
resources :signs, shallow: true, only: [:index]
end
resources :carts, only: [:show, :update]#, param: :cart_permalink
resource :cart, as: :user_cart, only: [:show, :update], param: :cart_permalink do
resources :cart_entries, only: [:index, :create, :update, :destroy], as: 'entries', path: 'entries'
end
resource :user, only: [:edit, :show, :update], as: 'current_user', path: 'profile'
resources :signs, only: [:show]
resources :pages, only: [:show], param: :permalink
and my show.html.erb has this form :
<%= form_for #cart, :url => {:controller => "carts", :action => "update" } do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :regnum %>
<%= f.text_field :regnum %></br>
<%= button_to "Order/update", {:controller => "carts",:action =>
'update', :id => #cart.id }, :method => :update %>
<% end %>
After i enter name or number (for example), and click update button or something, it doesnt upload any data into model carts(which has the right columns).
Thanks,
Michael
Your update method is private; controller actions need to be public. Move
def update
#cart = Cart.find(params[:id])
...
end
to be above the
private
line. You need to do the find on the Cart model, not a #cart instance.
You can use a show action although edit would be more standard and fits right in with the RESTful routes without the need to override convention. The Rails routing guide should help here: http://guides.rubyonrails.org/routing.html
Additionally, you need to define the value of #cart in your edit action:
def edit
#cart = Cart.find(params[:id])
end
This will ensure it has a value on the edit form and so comes back into your update action through the parameters.
So if you try to edit a cart with something like /carts/12345/edit (where 12345 is the id of the cart you want to update) it should all hang together.
This looks wrong:
#cart = #cart.find...
don't you mean...?:
#cart = Cart.find...
And it seems you are using "cart_permalink" instead of "id" on your routes
resource :cart, as: :user_cart, only: [:show, :update], param: :cart_permalink do
Check the server log and see the name of the parameter that holds the ID, also run "bundle exec rake routes" to double check.

Resources