My CREATE & DELETE routes not working do not understand why? - ruby-on-rails

Hello I am trying to create a bookmark feature in my app. I have created the
model I want to bookmark (Hairstyle), I also have a User model and a "Saved_Hairstyle" model which is the join table in the scenario.
In my routes.rb file I added a CREATE & DELETE route. In my controller I wrote out the CREATE & DELETE methods. I then proceeded to link_to my CREATE & DELETE methods paths in my View.
I would like that when I click on the CREATE Link a POST method is fired so that I can show an element on the page as being "bookmarked" and when I click the DELETE link a DELETE method is fired so that I can show an element on the page as being "unboomarked" but they don't work.
When I do RAILS ROUTES in Rails C I can see the right pathways but when I click through the links don't do anything.
Repo for ease of understanding: https://github.com/Angela-Inniss/hair-do
routes.rb
Rails.application.routes.draw do
root to: 'pages#home'
devise_for :users
resources :hairstyles do
member do
put "like", to: "hairstyles#upvote"
put "dislike", to: "hairstyles#downvote"
end
resources :comments, only: :create
resources :saved_hairstyles, only: [:new,:create]
end
resources :saved_hairstyles, only: :destroy
resources :comments, only: :destroy
resources :hairdressers
end
class SavedHairstylesController < ApplicationController
def create
#hairstyle = Hairstyle.find(params[:hairstyle_id])
#saved_hairstyle = SavedHairstyle.new(user: current_user, hairstyle: #hairstyle)
if #saved_hairstyle.save
respond_to do |format|
format.html { redirect_to hairstyle_path(#saved_hairstyle.hairstyle) }
format.js # <-- will render `app/views/comments/create.js.erb`
end
else
respond_to do |format|
format.html { render 'hairstyles' }
format.js # <-- idem
end
end
end
end
def destroy
#saved_hairstyle = SavedHairstyle.find(params[:id])
#saved_hairstyle.destroy
#hairstyle = #saved_hairstyle.hairstyle
respond_to do |format|
format.html { redirect_to hairstyle_path(#saved_hairstyle.hairstyle }
format.js
end
end
view.html.erb
<div class="bookmark">
<% saved_hairstyle = SavedHairstyle.find_by(user: current_user, hairstyle: hairstyle.id) %>
<% if saved_hairstyle %>
<%= link_to hairstyle_saved_hairstyle_path(saved_hairstyle), method: :post do %>
<i class="fas fa-plus"></i>
<% end %>
<% else %>
<%= link_to saved_hairstyle_path(hairstyle), method: :delete do %>
<i class="fas fa-plus-circle"></i>
<% end %>
<% end %>
</div>
create.js.erb file (this is what I Would like to happen on the POST request (i have something similar for the DELETE request)
plusCircle = document.getElementById("bookmark");
plusCircle.innerHTML = `<%= link_to '#', method: :post do %>
<i class="fas fa-plus"></i>
<% end %>`

There seems to be some errors in your view logic. You are loading saved hairstyles and try to book mark it again. You're also trying to delete a saved hairstyle if it doesn't exist. The path helpers also seem to be wrong (delete method is not nested and nested resources should be plural). Maybe it should look something like this:
<div class="bookmark">
<% saved_hairstyle = SavedHairstyle.find_by(user: current_user, hairstyle: hairstyle.id) %>
<% if saved_hairstyle %>
<%= link_to saved_hairstyle_path(saved_hairstyle), method: :delete do %>
<i class="fas fa-plus-circle"></i>
<% end %>
<% else %>
<%= link_to hairstyle_saved_hairstyles_path(hairstyle), method: :post do %>
<i class="fas fa-plus"></i>
<% end %>
<% end %>
</div>
By the way, if you check your console, you probably will see some errors that would point you to the right direction. You should also move saved_hairstyle query to a helper method.

Related

Delete method Rails - No route matches [GET] "/bookmarks/11"

My delete method for bookmarks does not seem to work, is this a problem with rails 7 or am I doing something wrong. It states that there is no Get method. I am using turbo-pack methods vs webpack
below is all relevant documents
routes.rb
Rails.application.routes.draw do
root 'lists#index'
resources :lists, except: [:edit, :update] do
resources :bookmarks, only: [:new, :create]
end
resources :bookmarks, only: :destroy
end
bookmarks_controller.rb
class BookmarksController < ApplicationController
before_action :set_bookmark, only: :destroy
before_action :set_list, only: [:new, :create]
def new
#bookmark = Bookmark.new
end
def create
#bookmark = Bookmark.new(bookmark_params)
#bookmark.list = #list
if #bookmark.save
redirect_to list_path(#list)
else
render :new
end
end
def destroy
#bookmark.destroy
redirect_to list_path(#bookmark.list), status: :see_other
end
private
def bookmark_params
params.require(:bookmark).permit(:comment, :movie_id)
end
def set_bookmark
#bookmark = Bookmark.find(params[:id])
end
def set_list
#list = List.find(params[:list_id])
end
end
show.html.erb
<div class="row">
<% #list.movies.each do |movie|%>
<% bookmark = Bookmark.find_by(list: #list, movie: movie) %>
<div class="col-12 col-lg-4">
<div class="card text-center text-white" style="background-color:#ffa82e00;">
<div class="card photo" class="card-img-top">
<%= image_tag(movie.poster_url, class: "card-img-top" )%>
<div class="card-body">
<h5 class="card-title text-dark"><%= movie.title%></h5>
<p class="card-text text-body"><%= movie.overview %></p>
<p class="card-text text-body"><%= bookmark.comment%></p>
<%= link_to "delete", bookmark_path(bookmark), data: { turbo_method: :delete, turbo_confirm: "Are you sure you want to remove #{movie.title} from your #{#list.name} list"}, class: 'text-danger' %>
</div>
</div>
</div>
</div>
<% end %>
<%= link_to "Bookmark now", new_list_bookmark_path(#list), class: "btn btn-primary" %>
Just use button_to instead which creates an actual form element and works even without relying on JavaScript:
<%= button_to "delete",
bookmark,
data: {
turbo_confirm: "Are you sure you want to remove #{movie.title} from your #{#list.name} list"
},
method: :delete,
class: 'text-danger'
%>
This has additional benefits to accessibility and the historical reasons why Rails used links and JS to turn clicking a link into a form submission are largely irrelevant in 2023. This is a feature that Turbo just provides for backwards compatibly.
As to why it doesn't work:
Turbo isn't properly included.
You have an error in your javascript thats preventing the event handler from doing its job.
You have a conflicting event handler.
It's the wrong phase of the planets...
I think it's because you are using link_to which will send a GET request. Try using button_for instead.

How do I connect routes to partials?

I am working on a rails app, where one of the tabs (the user show view) has a partial that is an inner navbar of sorts. There are three links (match, activity, message), each of which correspond to a different partial that is rendered to the right of the inner navbar.
Each of the partials has a corresponding route in my routes.rb file, but they are all rendered within one controller action (user#show). As a result, my inner navbar links alone are bringing the page to the proper route, but aren't successfully rendering the partials. To resolve this, I am checking within the view for what the end of the route is, and rendering the appropriate partial accordingly.
I imagine that there is a more ideal way to accomplish what I am looking to do, but I've had trouble figuring out what that might be.
I know that I could use separate view files instead of partials to resolve this, but for the sake of modularity, I would rather not move in that direction. Is there a better way for me to link routes to the appropriate partials?
routes.rb
Rails.application.routes.draw do
mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
resources :messages
resources :replies
resources :posts
resources :organizations
resources :users
resources :sessions
resources :matches
root "welcome#index"
get "/users/:id/match", to: "users#show", as: "user_match"
get "/users/:id/activity", to: "users#show", as: "user_activity"
get "/users/:id/message", to: "users#show", as: "user_message"
end
users_controller
class UsersController < ApplicationController
skip_before_action :verify_authenticity_token, only: [:create]
def show
#user = User.find(params[:id])
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
log_in #user
flash[:notice] = "Your account was created!"
redirect_to #user
else
flash[:alert] = #user.errors.full_messages.join(", ")
render 'new'
end
end
private
def user_params
params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation)
end
end
/users/show.html.erb
<div class="row">
<% if #user.id == current_user.id %>
<div class="col-md-2 justify-content-start">
<div>
<ul>
<li>
<%= link_to(user_message_path(current_user.id)) do %>
<%= fa_icon "envelope", text: "Messages" %>
<% end %>
</li>
<li>
<%= link_to(user_activity_path(current_user.id)) do %>
<%= fa_icon "comments", text: "Activity" %>
<% end %>
</li>
<li>
<%= link_to(user_match_path(current_user.id)) do %>
<%= fa_icon "handshake-o", text: "Matches" %>
<% end %>
</li>
</ul>
</div>
</div>
<% end %>
<div class="col-md-10 justify-content-center">
<% last = request.path.split('/').last%>
<% if #user.id == current_user.id %>
<% if last == "match" %>
<%= render partial: "match" %>
<% elsif last == "activity" %>
<%= render partial: "activity" %>
<% elsif last == "message" %>
<%= render partial: "message" %>
<% else %>
<%= render partial: "home"%>
<% end %>
<% else %>
<%= render partial: "home" %>
<% end %>
</div>
</div>
You have a few alternative approaches you could take, like setting each sub-page up as a new controller (UserMatchesController, etc.) and routing to them directly, or using AJAX to load the sub-sections dynamically, but your approach isn't bad. What I would do to improve on it is to make the sub-page a named segment in the route with a constraint to lock it down:
get "/users/:id/:section", to: "users#show", constraints: { section: /^(message|home|match|activity)$/ }
You can link to each section by passing that parameter as an argument:
link_to user_path(current_user.id, section: "message")
And then in your template, something like:
render partial: params[:section]

Rails Error: ActiveRecord::RecordNotFound

I am working on my first Rails project and I am running into a persistent issue. I suspect it has something to do with the routing, however, I can't seem to find anything about it online.
I assume it a rather simple fix, so please take a look and let me know if you can help.
TL;DR
What I was trying to achieve
Account detail Cards display Name, Phone number, and a note.
A delete and edit button would allow users to delete or edit.
What is happening:
Edit and Delete buttons return a weird param.
see image
Image of error, Showing Rails getting a different ID
Controller
class AccountdetailsController < ApplicationController
def index
#accountdetail = Accountdetail.all
end
#I can't find the ID to show the relevent card.
def show
#accountdetail = Accountdetail.find(params[:id])
if #accountdetail.nil?
redirect_to accountdetail_path
end
end
def new
#accountdetail = Accountdetail.new
end
def edit
#accountdetail = Accountdetail.find(params[:id])
end
def create
#accountdetail = Accountdetail.new(accountdetail_params)
if #accountdetail.save
redirect_to #accountdetail
else
render 'new'
end
end
#it affects this
def update
#accountdetail = Accountdetail.find(params[:id])
if #accountdetail.update(accountdetail_params)
redirect_to accountdetail
else
render 'edit'
end
end
#and this
def destroy
#accountdetail = Accountdetail.find(params[:id])
#accountdetail.destroy
redirect_to accountdetail_path
end
private def accountdetail_params
params.require(:accountdetail).permit(:first_name, :last_name, :phone, :notes, :id)
end
end
Index.HTML.ERB
<div class="ui card">
<div class="content">
<a class="header"><%= account.first_name %> <%= account.last_name %> </a>
<div class="meta">
<span class="date"><%= account.phone %></span>
<strong><p><%= account.notes %></p></strong> <br>
<%= link_to "edit", edit_accountdetail_path(#accountdetail) %>
<%= link_to 'Inspect', accountdetail_path(#accountdetail) %>
</div>
</div>
</div>
<% end %>
Routes
Rails.application.routes.draw do
get 'welcome/index'
resources :articles do
resources :comments
end
resources :accountdetails
root 'welcome#index'
end
In you index.html.erb replace following
<%= link_to "edit", edit_accountdetail_path(#accountdetail) %>
<%= link_to 'Inspect', accountdetail_path(#accountdetail) %>
with
<%= link_to "edit", edit_accountdetail_path(account) %>
<%= link_to 'Inspect', accountdetail_path(account) %>
#accountdetail was providing you all the records of account, as it was firing select query in controller. But here we need only one instance, so account.
Hope this helps.

Rails error while working through JumpStartLabs Blogger 2 Tutorial(trying to implement tag deletion)

I've been fighting with this error for a while now and I'm sure that it is something simple that I am missing. I'm working through the Blogger 2 tutorial by jumpstartlabs(http://tutorials.jumpstartlab.com/projects/blogger.html#i3:-tagging).
I'm attempting to implement a way to delete existing tags through the UI. I'm stuck trying to resolve this error:
No route matches [POST] "/tags/3"
My routes.rb is:
Blogger::Application.routes.draw do
root to: 'articles#index'
resources :articles do
resources :comments
end
resources :tags
end
and here is my tags controller:
class TagsController < ApplicationController
def show
#tag = Tag.find(params[:id])
end
def index
#tags = Tag.all
end
def destroy
#tag = Tag.find(params[:id])
#tag.destroy
flash.notice = "Tag '#{#tag.name}' Deleted!"
redirect_to action: 'index'
end
end
Finally, here is the page that I'm displaying the deletion link on:
<h1>All Tags</h1>
<ul id="tags">
<% #tags.each do |tag| %>
<li>
<%= link_to tag.name, tag_path(tag), class: 'tag_title' %>
<%= link_to "Delete", tag_path(tag), method: :destroy, data: {confirm: "Really delete the tag?"} %>
</li>
<% end %>
<%= link_to "<< Back to Articles List", articles_path %>
</ul>
As #BillTurner mentioned, try changing method from :destroy to :delete. Make sure you save the change, reboot the server, and let me know if that works.
that answer didn't work out for me, but I found elsewhere that => fixed it
<%= link_to "delete", article_path(#article), :method => :delete, data: {confirm: "Really delete the article?"} %>
(that's in the view app\views\articles\show.html.erb)

No route error for nested resources in Rails

Hi this is my first time using nested resources. I did rake routes and found a path to new_user_album_path, but it doesn't seem to work. Could the problem be because I did a double nest?
The problem is specifically when I click a link in my Users views file named show.html.erb . Trying to link to a "create an album" page but that's when it shows me an error:
No route matches {:action=>"new", :controller=>"albums"}
Here are my files:
show.html.erb
<% provide(:title, "Welcome, #{#user.name}!") %>
<div>
You currently have <%= pluralize(#user.albums.count, "album") %>
</div>
<div>
<%= link_to "Create a new album!", new_user_album_path %>
</div>
<div>
<% if #user.albums.any? %>
hey
<% else %>
boo
<% end %>
</div>
<%= link_to "Back", users_path %>
Config/routes
Pholder::Application.routes.draw do
resources :users do
resources :albums do
resources :pictures
end
end
Controller
class AlbumsController < ApplicationController
def index
#albums = Albums.all
respond_to do |format|
format.html
format.json { render json: #albums }
end
end
def new
#user = User.find(params[:user_id])
end
end
You need to pass the user to the route method, like:
new_user_album_path(#user)

Resources