How to pass an id in URL to controller? Rails - ruby-on-rails

I want to deal with some data rows with same key_id. I want them to get select by using an id in URL, so I will have /field_data/index/12 and 12 here means the key_id.
I can manually do it in the controller by hardcoding the key_id
def index
#key_id = 12
#field_data = FieldDatum.select('field_content').where("key_id = ?", #key_id)
end
and my URL is very general: /field_data
So how to make it be able to get the id in URL?

routes
get "/field_data/index/:key_id", to: "field_datas#index"
controller
def index
#field_data = FieldDatum.select('field_content').where(key_id: params[:key_id])
end

Try this:
Show.html.erb
<% user_all.each do |user| %>
<%= link_to user_id_pass_path(user.id), method: :get do %>
<span class="btn btn-warning">Pass Id</span>
<% end %>
<% end %>
routes.rb
get '/user_id_pass/:id' => 'users#user_id_pass', as: 'user_id_pass'
users_controller.rb
def user_id_pass
#user = User.find_by_id(params[:id])
end

Related

Get the id of a User through a form or a search box on ruby

I am currently working on a Friendship feature. I would like to let the user select or type the name of another user in order to send a friend request.
Here is my form :
<%= form_tag users_path, method: 'get' do %>
<%= label_tag(:search, "Who are your friends ?") %>
<%= text_field_tag :search, params[:search] %>
<%= link_to user_friendsips_path(), method: :post do %>
<button class= "btn btn-user shadow"> <i class="fas fa-share-square"></i> Send Friend Request? </button>
<% end %>
<% end %>
In the link_to where there is the button I would like to pass between the bracket the user_id the person selected in the form but I don't know how to retrieve it
Here is a part of my User Model
def self.search(search)
if search
user_pseudo = User.find_by(pseudo: search)
if user_pseudo
self.where(user_id: user_pseudo)
else
#users = User.all
end
else
#users = User.all
end
end
Here is a part of my User controller with the Index
def index
#friends = current_user.friends
#pending_requests = current_user.pending_requests
#friend_requests = current_user.received_requests
#users = User.search(params[:search])
end
Thanks by advance
self.where(user_id: user_pseudo)
## I think you need to replace user_id with just id
##or Provide more details please

RoR - how to make an .each loop on views pass a variable to the controller

Im trying to add votes to comments on my blog application. But i cant seem to be able to send the variable within the below loop to the controller:
<% #comments.each do |c| %>
<h1><%= c.title %></h1>
<p><%= c.content %></p>
<p><%= c.user.username %></p>
<% if current_user.id == c.user_id %>
<%= link_to "Edit", edit_comment_path(#post, c)%>
<%= link_to "Delete", delete_comment_path(#post, c), method: :delete, data: { confirm: "Are you sure?" }%>
<% end %>
<% if current_user.id != c.user_id %>
<p>Review this comment</p>
<%= link_to like_path(c), method: :put do %>
Upvote
<%= c.upvote %>
<% end %>
<%= link_to dislike_path(c), method: :put do %>
Downvote
<%= c.downvote %>
<% end %>
<% end %>
<% end %>
controller:
...
def upvote
object_comment = Comment.find(#comment.id)
object_comment.increment!(:upvote)
redirect_to show_path(#post)
end
def downvote
object_comment = Comment.find(#comment.id)
object_comment.increment!(:downvote)
redirect_to show_path(#post)
end
....
Routes:
Rails.application.routes.draw do
....
#Comments
post '/post/:post_id', to: 'comment#create', as: 'new_comments'
get '/post/:post_id/:comment_id/edit', to: 'comment#edit', as: 'edit_comment'
put '/post/:post_id/comment/:comment_id', to: 'comment#update', as: 'update_comment'
delete '/post/:id/:comment_id/', to: 'comment#destroy', as: 'delete_comment'
put 'like', to: "comment#upvote", as: 'like'
put 'dislike', to: "comment#downvote", as: 'dislike'
end
I would like to receive the 'c' stated on the each loop as a variable on the upvote and downvote methods to replace the #comment within object_comment = Comment.find(#comment.id), in order to increment the votes. is this possible?
As it is right i obviously receive the following error:
NoMethodError (undefined method `id' for nil:NilClass):
Your *_path methods do not know what to do with that single argument. (If you want to pass an object to your links, you might want to research RESTful routing. However, to solve it with your current routes, I suggest
<%= link_to "Downvote #{c.downvote}" dislike_path(id: c.id) %>
It should then be possible to access this id attribute in the controller via params.
def dislike
#comment = Comment.find(params[:id])
...
end
A couple of other things to think about:
It's very unusual to perform a put action on clicking a link. You might want to consider doing this as a get action instead.
Does the downvote method return something which is different for each comment? If not, it's standard practise to include it in the controller's helper.
You can get id in parameters, please check below methods
def upvote
object_comment = Comment.find(params[:id])
object_comment.increment!(:upvote)
redirect_to show_path(#post)
end
def downvote
object_comment = Comment.find(params[:id])
object_comment.increment!(:downvote)
redirect_to show_path(#post)
end
....
I think you're doing it wrong. You'll need to save the user's action on the comment with a model CommentVote for example that belongs to user and comment.
Then you'll need to do something like:
class CommentVote
belongs_to :comment
belongs_to :user
enum type: [:upvote, :downvote]
def self.vote(type:, comment_id:, user_id:)
comment_vote = CommentVote.where(comment_id: comment_id, user_id: user_id).first_or_initialize
comment_vote.type = type
comment_vote.save
end
end
And then do a after_save :update_counts in the CommentVote model:
def update_counts
self.comment.upvote = self.comment.comment_votes.upvote.count
self.comment.downvote = self.comment.comment_votes.downvote.count
self.comment.save
end
and you'll call it like: CommentVote.vote(type: :upvote, comment_id: 1, user_id: 1)

How to add a button to delete data without using params?

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.

Controller not receiving object id

I am trying to pass the category.id to the shop/index controller using
<% Category.all.each do |category| %>
<div><%= link_to category.name.titleize, shop_index_path :category_id => category.id %></div>
<hr>
<% end %>
Controller:
class ShopController < ApplicationController
def index
#products = Category.find(params[:category_id]).products
end
end
Where a category has many products. But Whenever I click the link I get
Couldn't find Category without an ID
Can anyone see why this is?
EDIT: This is the route I use
get 'shop/index'
try add params:
shop_index_path(params: { category_id: category.id })
You need refine you routes for passing params:
get 'shop/index/:category_id', to: 'shop#index'
And now you can pass category_id to path helper like:
shop_index_path(category.id)
It should be
<%= link_to category.name.titleize, shop_index_path(category.id) %>
Surely you could just use:
shop_index_path(category.id)
And then load:
Category.find(params[:id]).products

How do i access an id from the link?

I am displaying list of cities from the database ,each as a link.I want when a user click on any of the cities ,the action respond by grabbng the id of that city and re use it on the next action(show action in this case).So How do you grab an id from the link?Below is my idea which didnt work.Thank you in advance.
View/cities
<%#cities.each do |city| %>
<%=city.name%><br/>
<%end%>
Controller
Class DealController < ApplicationController
def all_cities
#cities=City.find(:all)
end
def city
#city=City.find(params[:city_id])
session[:city_id] = #city.id
redirect_to :controller=>"deal",:action=>"show"
end
def show
unless session[:city_id].nil? || session[:city_id].blank?
#city = City.find(session[:city_id])
#deals=#city.deals
end
end
routes
get "deal/city"
match 'deal/city' => "deal#city"
You are not passing the city_id in the link. Try:
<% #cities.each do |city| %>
<%= city.name %><br/>
<% end %>
If you want the link to be like "/deal/city/1" and get 1 as params[:city_id], you can modify your routes like this:
match 'deal/city/:city_id' => "deal#city", :via => :get
and use the link like this:
<% #cities.each do |city| %>
<%= city.name %><br/>
<% end %>

Resources