I'm trying to setup a post editing page, with links to edit and delete posts. I'm having troubles because my edit controller somehow doesn't seem to receive the parameters I'm sending. I've printed them out on the page to make sure they're there, and it displays correctly, but when I click the editlink I get ActiveRecord::RecordNotFound Couldn't find Article with 'id'= .
here's the view with the link: (article.id display correctly on this one)
<div id= "articles-index">
<div class = "row">
<% #article.each do |article| %>
<div class="row">
<div class = "container">
<p><%= link_to article.title, article %> | <%= article.updated_at.strftime("%e. %b %Y, %H:%M") %> | <%= link_to 'edit', articles_update_path(article.id) %> | delete</p>
<h2><%= article.id %></h2>
</div>
</div>
<% end %>
</div>
</div>
articles controller:(the ... is where I edited more code out as it's irrelevant to this question)
class ArticlesController < ApplicationController
...
def update
#article = Article.find(params[:id])
end
def manage
#article = current_user.articles
#article = current_user.articles.order('id DESC')
end
...
def article_params
params.require(:article).permit(:id, :title, :body, :user_id)
end
end
routes:
get 'articles/edit'
get 'articles/destroy'
get 'articles/manage'
get 'articles/show'
get 'articles/index'
get 'articles/new'
get 'articles/update'
get 'articles/search'
get 'articles/create'
get 'sessions/destroy'
get 'sessions/new'
get 'users/new'
resources :users
resources :sessions
resources :articles
GitHub Link
Clicking on a link instigates a GET request. I'm guessing the update action on your controller will be expecting the params to be a POST request.
The edit action normally handles GET.
The update action receives the POST request.
I was trying to find the DHH 2007 Keynote at Railsconf that covers this really well. If you can find it, watch it.
See CRUD Verbs and Actions at Rails Guides
UPDATE: Just seen your routes file. If it's a GET request then just put the URL directly into the browser. e.g.
articles/update?id=123
See if params[:id] == 123 in the controller. It should be.
UPDATE 2
articles_update_path(id: article.id)
Will generate a params has with an :id key but fundamentally you shouldn't be calling update actions with a GET route.
Related
Simple rails question (new to the community) and am having some trouble getting the following to work properly. Could somebody point out what I may be doing incorrectly?
I have a model called option that stores rows of options, and has a column, vote_count, that needs incremented by 1 every time the button below is clicked.
Here is my code:
Routes is below, here I want to use the vote route for the controller and button.
Rails.application.routes.draw do
post '/vote', to: 'responds#vote', as: 'vote'
resources :polls, except: %i( show new ) do
resources :options, only: %i( create update destroy )
resource :respond
resource :visualization, only: %i( show )
end
root "polls#index"
end
Responds Controller
class RespondsController < ApplicationController
def vote
#option = option.find(1)
#option.vote_count += 1
#option.save
end
before_action :set_poll
private
def set_poll
#poll = Poll.find(params[:poll_id])
end
end
Here is the HTML
<%= stylesheet_link_tag 'application.css' %>
<div class='flex items-center'>
<div class='w-full'>
<div class='text-gray-700 text-3xl'>
<%= option.title %>
<div class="vote-count2">
<%= button_to "Click To Vote!", vote_path, class: 'vote_count' %>
</div>
Total Vote Count: <%= option.vote_count %> |
Option ID: <%= option.id %>
</div>
</div>
</div>
Everything is rendering properly, no errors, I am just unsure how to get the votes to increment and update in the db properly (sqlite).
You need an HTML <form> wrapping that button to POST to your vote route.
See here for more details: https://guides.rubyonrails.org/v6.1/form_helpers.html
Getting back into programming but I'm having trouble with this basic thing. So I've scraped products from a web site then inserted them into a DB. Then I list those products on my web site. Now I'm trying to add a delete button next to each of those product that are listed on my web site. I've tried using the solutions found on stackoverflow but I can't seem to get any of them to work. I know this is a basic question, but I appreciate the help.
Controller
class IbottaController < ApplicationController
def save
require 'watir'
require 'phantomjs'
#browser = Watir::Browser.new:phantomjs
#browser.goto "https://ibotta.com/rebates"
#button = #browser.button(class: "see-more-label")
Ibotta.delete_all
# if x = 24 then I get 492 products
# if x = 23 then I get 472 products
x = 24
y = 0
while y < x
#button.click
y+=1
end
#products = #browser.divs(class: "offer-card")
#products.each do |a|
# if Ibotta.find_by title: a.imgs[0].alt
if a.divs[2].text.split("").include?('%')
else
value_placeholder = a.divs[3].text.split(" ")
value_placeholder.delete("cash")
value_placeholder.delete("back")
value_placeholder = value_placeholder.join(" ").split("")
value_placeholder.delete("$")
value_placeholder = value_placeholder.join("")
Ibotta.create(title: a.imgs[0].alt, values: value_placeholder, store: a.divs[5].text, link: a.links[0].href)
end
end
#products = Ibotta.all
end
def show
#products = Ibotta.all
end
def delete
Ibotta.delete_all
#products = Ibotta.all
end
def practice
end
end
View
<h1>Show Page for iBotta</h1>
<h3><%= #products.length %> products in the iBotta DB</h3>
<% #products.each do |x| %>
<p>Title: <a href=<%=x.link%>><%= x.title %></a> </p>
<p>Value: <%= x.values %> </p>
<p>Store: <%= x.store %> </p>
<% end %>
If you also have advice on what code I need to add, could you mention what file to add the code in? Thanks.
Routes
Rails.application.routes.draw do
resources :articles
get 'scraper/ibotta'
get 'scraper/checkout51'
get 'ibotta/save'
get 'ibotta/show'
get 'ibotta/delete'
get 'targetcoupon/save'
get 'targetcoupon/delete'
get 'targetcoupon/show'
get 'targetibottum/delete'
get 'targetibottum/show'
get 'targetibottum/save'
get 'savingstar/delete'
get 'savingstar/save'
get 'savingstar/show'
get 'ibottasavingstar/show'
get 'ibottasavingstar/save'
get 'ibottasavingstar/delete'
get 'targetcoupon/practice'
get 'targetibottasavingstar/show'
get 'targetibottasavingstar/save'
get 'targetibottasavingstar/delete'
get 'checkout51/save'
get 'checkout51/show'
get 'checkout51/delete'
get 'checkout51/practice'
get 'ibotta/practice'
get 'ibottacheckout51/save'
get 'ibottacheckout51/show'
get 'ibottacheckout51/delete'
get 'ibottacheckout51/practice'
get 'newcheckout51/save'
get 'newcheckout51/show'
get 'newcheckout51/delete'
get 'smiths/save'
get 'smiths/show'
get 'smiths/delete'
get 'smiths/practice'
Why don't You want to use params? I do not know If It is even possible...
With ID You could simply add something like <%= link_to 'delete', ibotta_path(x.id), method: :delete %> In Your view.
If You have resources routes the path helper should be avaliable for You.
Then in controller add:
def destroy
Ibotta.find(params[:id]).destroy
redirect_to your_redirect_path
end
EDIT: I see that You are not using resources routing - add delete 'ibotta/:id', to: 'ibotta#destroy' to Your routes.rb or just use resources routing
So Your view would look like:
<% #products.each do |x| %>
<p>Title: <a href=<%=x.link%>><%= x.title %></a> </p>
<p>Value: <%= x.values %> </p>
<p>Store: <%= x.store %> </p>
<p><%= link_to 'delete', ibotta_path(x.id), method: :delete %></p>
<% end %>
One note - I think You shouldn't use variable names like 'x' in each block, use 'product' instead, it is much more descriptive.
So I am working on this rails project. I am trying to get an input from the view and pass it into the controller, so it can be saved into a variable for later use.
I have my view layer in /views/welcome/index.html.erb with the following :
<div class="locator-input">
<%= text_field_tag :user_input %>
<%= submit_tag "Get started" %>
</div>
and the controller in /controller/welcome_controller.rb
class WelcomeController < ApplicationController
def index
end
def locator
#user_input = params['user_input']
end
end
and routes.rb here
Rails.application.routes.draw do
root 'welcome#index'
end
so when I go ahead and hit submit, I get this error:
I know this error has something to do with routes.rb but I can't figure out how to fix it.
My ultimate goal is to get user input, pass it into the controller and save it into a variable to I can use it with my model later on.
I will greatly appreciate some guidance from our experts.
Thanks.
The route generate with root expects only GET requests. But your form sends a POST request.
To solve this just add the following to your config/routes.rb:
root 'welcome#index'
match '/', to: 'welcome#index', via: [:post]
Wrap the field in a form
<div class="locator-input">
<%= form_tag locator_welcome_path %>
<%= text_field_tag :user_input %>
<%= submit_tag "Get started" %>
<% end %>
</div>
You also need to create a route
Rails.application.routes.draw do
resource :welcome, controller: :welcome do
post :locator
end
root 'welcome#index'
end
This will generate
locator_welcome POST /welcome/locator(.:format) welcome#locator
I was making a blog and I've got problem when I want to show an article
I've generate scaffold article title content:text and I just generate new controller called welcome with a view called homepage. I created new controller+view just to show articles. for this part I did not find the problem and then I created a new controller called post with a view called show is intended only to show the contents of the selected articles from the homepage.
how to show article's content from another view ?
I just added #article = Article.find(params[:id]) to post_controller
and then when I click an article's title in homepage I got error like this
Couldn't find Article with 'id'=
did I miss some code?
so this is my welcome_controller
class WelcomeController < ApplicationController
def homepage
#articles = Article.all
end
end
welcome/homepage.html.erb
<div class="post-preview">
<% #articles.each do |article|%>
<h2 class="post-title"><%= link_to article.title, welcome_show_path %></h2>
<%= truncate article.content, length: 160 %>
<hr>
<% end %>
</div>
post/show.html.erb
<div class="post-heading">
<h1><%= #article.title %></h1>
</div>
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
<p><%= #article.content %></p>
</div>
post_controller
class PostController < ApplicationController
def show
#article = Article.find(params[:id])
end
end
routes.rb
Rails.application.routes.draw do
resources :articles
get 'welcome/homepage'
get 'post', to: 'post#show'
root 'welcome#homepage'
end
thanks :)
The problem seems to be in your link:
<h2 class="post-title"><%= link_to article.title, welcome_show_path %></h2>
welcome_show_path needs an id. Try welcome_show_path(id: article.id).
<h2 class="post-title"><%= link_to article.title, welcome_show_path(id: article.id) %></h2>
If that doesn't work, try: post_show_path(id: article.id).
You have 3 Controllers:
Article => generated by scaffolding, it means with predefined routes.
Welcome => only one method, called homepage
Post => only one method, called show.
Routes:
resources :articles ##generate default routes
get 'welcome/homepage' ##generate only one route, URL would be -> homepage_welcome_path.
get 'post', to: 'post#show' ##it will call show method without any parameter.
root 'welcome#homepage'
First:
get 'photos/:id', to: 'photos#show'
In your homepage.html.erb
<h2 class="post-title"><%= link_to article.title, welcome_show_path %></h2>
welcome_show_path ## expect show method in welcome controller, which is not exist.
Second:
To call show method of articles, you must pass ID of that article.
get 'articles/:id', to: 'articles#show' ##This route is already defined as you have `resource articles`. URL would be articles_path for the same.
Replace in homepage.html.erb
<h2 class="post-title"><%= link_to article.title, articles_path(id: article.id) %></h2>
I have a model that I want to be commentable. I am having difficulty creating a form on my model's 'show' view that will allow comments to be created. I am not finding any good or useful examples. Can anyone point me to or show me an example of how to do this?
Example:
A simple blog application. I have a model called Post. It is commentable. So on the 'show' view I want to show a Post and, at the bottom, have the fields that, when completed and submitted, create a new comment associated with the post and put it in the database.
Sounds straightforward and I have it working so I can display comments that I have seeded. I just can't get a form to work to put new ones in. Any help is appreciated.
Lets assume a Post model. Make sure, you have
class Post < ActiveRecord::Base
acts_as_commentable
end
then in the view of say Post#show
<%= form_tag "/posts/add_new_comment" do %>
<%= hidden_field_tag "id", post.id %>
<%= text_area_tag "comment[comment]" %>
<%= submit_tag "Post Comment" %>
<% end %>
then in the PostController
def add_new_comment
post = Post.find(params[:id])
post.comments << Post.new(params[:comment])
redirect_to :action => :show, :id => post
end
and in routes.rb
match "/posts/add_new_comment" => "posts#add_new_comment", :as => "add_new_comment_to_posts", :via => [:post]
Hope this gets u up and running.
This is very, very basic stuff and you clearly need some better structure and approach to your learning. Buying a book, such as Agile Web Development with Rails, is the only real way to learn, otherwise you'll wander from problem to problem without ever actually learning anything well.
Say you have a post that you want to comment.
#routes.rb
map.resources :posts do |post|
post.resources :comments
end
#post_controller.rb
def show
#post.find params[:id]
#comment = #post.comments.new
end
#posts/show.html.erb
<%- form_for [#post, #comment] do |f|-%>
<%= f.text_area :body -%>
<%= f.submit -%>
<%- end -%>
#comments_controller
def create
#post = #post.find params[:post_id]
#comment = #post.comments.new params[:comment]
if #comment.save
redirect_to #post
This is an old question, but I want to throw in my solution as well as the gem's README is still unhelpful after all these years. It builds upon #Kunday's answer. The following will be a tutorial to use the act_as_commentable gem to...
Allow users to create comments under each post.
Show all comments belonging to a post.
This assumes that you already have a working "blog", whether it be pictures or posts. Install gem, then run rails g comment to get started.
Allow users to create comments under each post.
First, inside the model that you want to use commentable gem, add the following line as suggested in the gem's README.
class Post < ActiveRecord::Base
acts_as_commentable
end
Then create a new comment controller with the create action. Please note that the :authenticate_user! is part of devise which is a gem for creating easy authentication. current_user is also part of devise as a helper. It is needed if you want to display the user's name/email under the comment body.
class CommentsController < ApplicationController
before_action :authenticate_user!
def create
post = Post.find_by(id: params[:id])
comment = post.comments.build(comment_params)
comment.user = current_user
if comment.save
flash[:notice] = "Comment has been created."
redirect_to post
else
flash[:alert] = "Comment has not been created."
end
end
private
def comment_params
params.permit(:comment)
end
end
Next, set up the routes. It's just this. This means that when someone sends a post request to comments, we will run to create action inside the comments controller.
post 'comments' => 'comments#create', as: "create_comment"
The as: "create_comment" gives it an alias, so you can do create_comment_path. Now, on the show view of Post, we'll add the form. The divs will help you add css.
<div class="comment-section">
<%= form_tag create_comment_path, method: "post" do %>
<%= hidden_field_tag "id", #post.id %>
<%= text_area_tag :comment %>
<%= submit_tag "Submit" %>
<% end %>
</div>
Now to show each comment under the Post show view.
The divs will help you add css, comment.user.name will work if your User class has a name column. Else, change it to email or whatever identifier you choose to use.
<div class="comment_list">
<% #comments.each do |comment| %>
<%= comment.comment %> <br>
<%= comment.user.name %> <br>
<br>
<% end %>
</div>
And finally, in order for #comments to exist in the show page, go to your Post controller, and under show, add the following:
def show
#post = Post.find_by(id: params[:id])
#comments = #post.comments.all
end
This should be good for the requirements. Good luck.