I'm programming a website with a friend, and I'm getting one error with my code. In the computer of my friend, he have the same code and don't have any error.
I get the following error:
We're sorry, but something went wrong.
Well, we're newbie in Rails and I get this error when I try to load the posts page. We think the error is on deleting a post, because if we comment the line of "posts_delete_path", everything works. For delete a post, we are using:
show.hmtl.erb:
<% #hashtag.posts.each do |p| %>
<li>Posted by: <%= p.user.name %></li>
<li>Content:</li>
<li><%= p.content %></li>
<li><a href="<%= posts_delete_path %>/<%= p.id %>" >Delete</a></li>
<% end %>
routes:
match '/signout', to: 'sessions#destroy'
match 'posts/delete/:id', to: 'posts#destroy'
resources :posts, :only => [:create, :show]
posts controller:
def destroy
#post = Post.find(params[:id])
if current_user.id == #post.user_id
#post.destroy
end
end
---- edit ----
rake routes:
posts GET /posts(.:format) posts#index
POST /posts(.:format) posts#create
new_post GET /posts/new(.:format) posts#new
edit_post GET /posts/:id/edit(.:format) posts#edit
post GET /posts/:id(.:format) posts#show
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
We know that's the newbie way to delete a post, but we don't find any better solution. (If you want suggest something, we will be glad too).
<%= link_to "Delete", p, method: :delete %>
and modify the routes.rb with
resources :posts
You should use the link_to notation like this:
<%= link_to "Delete", p, method: :delete %>
Also, you should try to stop users from even seeing the delete button in the view, something like:
<% if current_user == p.user %>
<%= link_to "Delete", p, method: :delete %>
<% end %>
This will only show the delete link only to the owner of the post.
Also like Ganesh said , turn this:
match 'posts/delete/:id', to: 'posts#destroy'
resources :posts, :only => [:create, :show]
to:
resources :posts, :only => [:create, :show, :destroy]
Checkout the routing system in the rails guides: http://guides.rubyonrails.org/routing.html, and see which of the routes you will need.
looks like ur link is fine, but sounds like you did not include your js, thats why it is redirecting you to the show page when you click delete.
<%= link_to 'Destroy', product, :confirm => 'Are you sure?', :method => :delete %>
1. Check your /assets/application.js for //= require jquery and
//= require jquery_ujs
Add in application.js this code
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
// GO AFTER THE REQUIRES BELOW.
//
//= require jquery
//= require jquery_ujs
//= require_tree .
2. Check your /layouts/application.html.erb for <%= javascript_include_tag "application"%>
<head>
<title>My awesome app</title>
<%= stylesheet_link_tag "application" %>
<%= javascript_include_tag "application"%>
<%= csrf_meta_tag %>
</head>
Thanks for everyone who tried help me. Now I solved my problem, but by other way.
What I do is:
In view:
<% if current_user.id == p.user_id %>
<%= button_to "Delete", { :controller => :posts, :action => 'destroy', :id => p.id }, :method => :delete %>
<% end %>
In controller:
def destroy
#post = Post.find(params[:id])
#if current_user.id == #post.user_id
#post.destroy
end
end
In routes:
resources :posts
Thanks guys!
Related
Working on versions:
Ruby: 3.0.2
Rails 6.1.4
I'm trying to put a button in my View template for "Users" that will set the :mod attribute to false, with the button just being "Demote User".
I had it working SOMEHOW using a helper method, demote_user, and some variation of
<% if logged_in? && current_user.admin? %>
<%= link_to "Demote User", user_path(#user), onclick: demote_user(#user), class: "btn btn-info" %>
<% end %>
I messed up however it was working when trying to move this method into a controller for best practice. I'm not sure what format worked out, but I've tried many such as
:onclick => demote_user(#user)
onclick: 'demote_user(#user)'
onclick=demote_user(#user)
onclick='demote_user(#user)
and etc. Somehow, it did eventually work but I busted it. Now, every time I load the User's page, it's just executing demote_user(#user) without even needing to click the button, so refreshing a User's page is demoting them.
I am now trying to do this properly by creating a demote method in the UserController, but I have NO IDEA how to make the route, or make it work properly. Up until now, all my routes have been working using resources, and the basic new, create, destroy, etc.
I've been trying many different routes, and view formatting, with no luck and usually ending up with just: Routing Error
No route matches [GET] "/demote.3"
I'd like to be able to avoid using the Javascript onClick functionality and do it properly with the controller even if I could remember how to make it work, but I think my route, or view page, or controller is incorrect. Here are the contents of each file:
Controller
def demote
byebug
#user = User.find(params[:id])
#user.mod = false
redirect_to user_path(#user)
end
View
div class="container text-center mt-4">
<% if logged_in? && current_user.admin? %>
<%= link_to "Demote User", demote_path(#user), class: "btn btn-info" %>
<% end %>
</div>
Routes
Rails.application.routes.draw do
root 'pages#home'
get 'about', to: 'pages#about'
resources :articles
get 'signup', to: 'users#new'
resources :users, except: [:new]
get 'login', to: 'sessions#new'
post 'login', to: 'sessions#create'
delete 'logout', to: 'sessions#destroy'
resources :categories
post 'demote', to: 'users#demote'
end
Up until now, I've been following a course, and I've nailed everything in it and have added some of my own functionality, but I'm still not quite sure how to make sense of routes, or what paths it creates.
I'd like to make other similar custom controller functions beyond show, index, create, delete, update which are all I really understand how to build. I'm not even sure if POST is the correct call in the route.
I would just setup an additional RESTful action for the resource:
resources :users do
patch :demote
end
<% if logged_in? && current_user.admin? %>
<%= button_to "Demote User", demote_user_path(#user), method: :patch %>
<% end %>
You can use link_to instead of button_to but you need to use the correct method: :patch or data: { turbo_method: :patch } option depending on your version of Rails to get the javascript driver to do its trickery.
I want to create a text field that accepts input and when you press the button next to it, it will save these changes to the database. It will be a PUT request, updating the value in the database for this specific user (not the logged in user, this is a page for admins to update values for users).
This is what the structure should be, (code to follow below):
1) Create text field and button for this in show.html.erb
2) Create a function called set_wistia_project_ID for this in users_controller.rb, set button equal to this :action
3) Create a helper function called set_project_id in user.rb that is called by set_wistia_project_ID, which actually updates the database. I decided to split it up into two functions because I noticed a lot of Rails projects tend to separate and break up functionality into the controller and model.
4) Edit my routes.rb to include some strange code, which I'll be honest, have no idea what it actually does. But without it, the entire app crashes on Heroku. So I leave it there. Found from a StackOverflow post.
My show.html.erb:
<% provide(:title, #user.name) %>
<div class="row">
<aside class="col-md-4">
<section class="user_info">
<h1>
<%= gravatar_for #user %>
<%= #user.name %>
<br>
<%= #user.email %>
<br>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(#user) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :wistia_project_id %>
<%= f.text_field :wistia_project_id, class: 'form-control' %>
<%= button_to "Save", :action => "set_wistia_project_ID", :method => :put, :form_class => "form-control" %>
</div>
</div>
</h1>
</section>
</aside>
</div>
My users_controller.rb:
# Sets wistia_project_ID.
def set_wistia_project_ID
#user = User.find(params[:id])
#user.set_project_id
end
My user.rb:
# Sets the wistia_project_ID.
def set_project_id
self.wistia_project_ID # HOW TO SET EQUAL TO INPUT?
end
My routes.rb:
Rails.application.routes.draw do
root 'static_pages#home'
get 'password_resets/new'
get 'password_resets/edit'
get 'sessions/new'
get '/help', to: 'static_pages#help'
get '/about', to: 'static_pages#about'
get '/contact', to: 'static_pages#contact'
get '/signup', to: 'users#new'
post '/signup', to: 'users#create'
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
resources :users do
member do
put 'set_wistia_project_ID'
end
end
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
end
But the problem I am having is that when I try to go to show.html.erb, my Heroku app crashes :(
The reason:
F, [2019-06-25T19:53:20.706881 #8] FATAL -- : [b2ed08bb-de52-417f-9ba8-8ec85629dce8]
app/views/users/show.html.erb:30:
syntax error, unexpected end-of-input, expecting end
But it looks fine to me?
The syntax error is that you are missing <% end %> for the <%= form_for(#user) do |f| %> block.
To answer your question about how to access the param in the model's method - you should pass it as an argument:
#user.set_project_id(params[:wistia_project_ID])
And change the method to accept an argument. Note, I am assuming you want to actually persist this to the database, so I'm adding a save call. You could alternatively call update which assigns the new value and saves in one go.
def set_project_id(val)
self.wistia_project_ID = val # self is necessary here
save # or self.save, but the self is unnecessary here
end
However, calling save does always succesfully save the record, there is still the possibility of an error if a model-level validation failed. You can handle this using flash: https://guides.rubyonrails.org/action_controller_overview.html#flash-now
or, if you don't need to redirect, can just use an instance variable to store the errors:
#user = User.find(params[:id])
#user.set_project_id(params[:wistia_project_ID])
unless #user.valid?
#errors = #user.errors.full_messages
render :show
end
and in the show view:
<% if #errors %>
<p>THE FORM COULD NOT BE SAVED </p>
<ul id='errors'>
<% #errors.each do |error| %>
<li><%= error %></li>
<% end %>
</ul>
<% end %>
Also note, I would probably rename your set_project_id method to set_project_id! (added a bang), to signify that it mutates the input (changes its internal state).
I recently did this tutorial http://www.reinteractive.net/posts/32-ruby-on-rails-3-2-blog-in-15-minutes-step-by-step, but im having trouble figuring out how to delete the comments once theyve been posted, ive tried the
method but that doesnt work as well as
it just return undefined method eror to me, what am i doing wrong
my code:
<%= div_for rep do %>
<p>
<div style="font-weight:bold; color:grey;"><%= rep.title %></div>
<div><%= rep.body %></div>
<strong style="font-size:8px;">
Posted <%= time_ago_in_words(rep.created_at) %> ago
</strong>
<br/>
<%= link_to 'Destroy', steppy_reps_path(#steppy, rep), method: :delete, data: { confirm: 'Are you sure?' } %>
</p>
<% end %>
the error:
No route matches [DELETE] "/steppies/11/reps.9"
routes.rb:
Testapp2::Application.routes.draw do
resources :steppies do
resources :reps, :only => [:create]
end
get "steppies/ask"
get "steppies/create"
get "steppy/ask"
get "steppy/create"
end
rake route output:
steppy_reps POST /steppies/:steppy_id/reps(.:format) reps#create
steppy_rep DELETE /steppies/:steppy_id/reps/:id(.:format) reps#destroy
steppies GET /steppies(.:format) steppies#index
POST /steppies(.:format) steppies#create
new_steppy GET /steppies/new(.:format) steppies#new
edit_steppy GET /steppies/:id/edit(.:format) steppies#edit
steppy GET /steppies/:id(.:format) steppies#show
PUT /steppies/:id(.:format) steppies#update
DELETE /steppies/:id(.:format) steppies#destroy
steppies_ask GET /steppies/ask(.:format) steppies#ask
teppies_create GET /steppies/create(.:format) steppies#create
steppy_ask GET /steppy/ask(.:format) steppy#ask
steppy_create GET /steppy/create(.:format) steppy#create
You need to add the action to your routes.rb file.
resources :steppies do
resources :reps, :only => [:create, :destroy]
end
Also, the form needs to use a different route.
steppy_rep_path(#steppy, rep)
I created a form to create articles, but I can only see the published articles on the index page, and, I'm unable to see individual articles.
Every time I click on 'show' for an individual article on the index, it opens a blank page with a URL like localhost:3000/articles.1, instead of localhost:3000/articles/1.
I don't know what's wrong with the code, it's similar to the code I have for creating and editing articles as admin and it works there, but I keep getting this error.
Here's the code:
views/articles/show.html.erb:
<h1><%= #article.name %></h1>
<%= #article.content %>
<%= image_tag #article.photo.url(:small) %>
<p>Tags: <%= raw article.tag_list.map { |t| link_to t, tag_path(t) }.join(', ') %></p>
<%= link_to 'Back', noticias_path %>
views/articles/index.html.erb:
<% #articles.each do |article| %>
<div>
<h2><%= article.name %></h2>
<%= article.content %>
<p><%= link_to 'Show', noticias_path(article) %></p>
<p>Tags: <%= raw article.tag_list.map { |t| link_to t, tag_path(t) }.join(', ') %></p>
</div>
<% end %>
articles_controller.rb:
# GET /articles/1
# GET /articles/1.json
def show
#article = Article.find(params[:id])
end
routes.rb:
Blog::Application.routes.draw do
root to: 'welcome#index'
get 'tags/:tag', to: 'noticias#index', as: :tag
get "noticias/index"
get "dashboard/index"
get "/sitemap" => "sitemap#index", :as => :sitemap, :defaults => {:format => :xml}
match '/noticias', to: 'noticias#index', via: 'get'
get 'login', to: 'sessions#new', as: 'login'
get 'logout', to: 'sessions#destroy', as: 'logout'
resources :users
resources :sessions
namespace :admin do
get '', to: 'dashboard#index', as: '/'
resources :noticias
end
end
It's more a problem with noticias_path, consider verify your routes with rake routes, but I think to change noticias_path to noticia_path, may can fixed it.
Based on your routes file, it looks like the problem is indeed incorrect routing. Presently, you are manually creating routes for RESTful resources, when you should simply let rails handle that for you properly.
Remove the manual get and match lines:
get "noticias/index"
match '/noticias', to: 'noticias#index', via: 'get'
And replace them with this:
resources :noticias
If noticias should be pointing to the ArticlesController (or any other controller), then simply do this:
resources :noticias, to: 'articles'
Also, Matheus Caceres was correct that the URL helper should in fact be noticia_path for the show action. The noticias_path points to the index action. Rails tries to be "helpful" by making routes, helpers, functions, etc, sound proper if read in English, but might not necessarily make sense for words in another language. I don't know if "noticia" makes any sense in Portuguese though.
Another quick side note, the two manual routing lines I indicated above are redundant; they would in fact both match a GET request and route them to noticias#index. However, keep in mind that routes are matched in the order they appear in the routing file, so the match line would never have been called, since the route would have matched on that get line.
I have a rails 3 app, and when I click the link to my terms page, it routes to a completely different controller, than what the routes should use. Stranger still, the route works when I'm not logged in, and I'm using devise.
I get this error when clicking the link when I'm logged in.
No route matches {:action=>"edit", :controller=>"users", :id=>nil}
<%= link_to "Terms", terms_path %>
Routes (in the order they appear in routes.rb):
devise_for :users, :controllers => {:registrations => "registrations"}
resources :users do
member do
get :following, :followers
post :accept
end
end
match '/terms', to: 'static_pages#user_agreement'
Static Pages Controller
def user_agreement
end
Rake Routes
terms /terms(.:format) static_pages#user_agreement
This also happens for every other action that I've routed this way to the staticpages controller, but not for any other actions that route to different controller.
Update: Terms Page
Header:
<%= link_to "Follow", users_path %>
<%= link_to current_user.name, current_user %>
<%= link_to "Sign out", destroy_user_session_path, :method => :delete %>
Footer:
<%= link_to "Welcome", welcome_path %>
<%= link_to "Settings", edit_user_path(#user) %>
<%= link_to "Terms", terms_path %>
All the content is pure html.
Thanks in advance
You have a link to edit_user_path with no #user as hinted in the comments.
You should almost certainly be using current_user anyway.