I've created a custom route make_winner_pick but every time I click the link to follow the path the controller defaults to the show action. I can't understand what I'm doing wrong and it's driving me nuts
routes.rb
resources :league_members
get "league_members/make_winner_pick" => "league_members#make_winner_pick", :as => :make_winner_pick
Where the path is called
<%= link_to 'Join League', make_winner_pick_path(league: league.id), method: :get %>
The console
Started GET "/league_members/make_winner_pick?league=3" for 127.0.0.1 at 2015-08-29 01:33:56 +0100
Processing by LeagueMembersController#show as HTML
Parameters: {"league"=>"3", "id"=>"make_winner_pick"}
User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."id" = 2 ORDER BY "users"."id" ASC LIMIT 1
LeagueMember Load (0.5ms) SELECT "league_members".* FROM "league_members" WHERE "league_members"."id" = $1 ORDER BY "league_members"."id" ASC LIMIT 1 [["id", 0]]
Completed 404 Not Found in 5ms
ActiveRecord::RecordNotFound (Couldn't find LeagueMember with 'id'=make_winner_pick):
app/controllers/league_members_controller.rb:68:in `set_league_member'
Can anyone tell me why my custom route is not being fired and Rails is defaulting to the #show action? For some reason it appears to be looking for a league_member with an id of make_winner_pick
Thanks for looking.
Try nest your route within the resource:
resources :league_members do
collection do
get "make_winner_pick" => "league_members#make_winner_pick", :as => :make_winner_pick
end
end
Because rails recognized your route make_winner_pick as an id.
it should be:
<%= link_to 'Join League', league_members_make_winner_pick_path(league: league.id), method: :get %>
Related
I have a model called Resource configured with:
class Resource < ActiveRecord::Base
has_many_attached :assets
end
I created an action in my resources_controller.rb as follows:
def delete_asset_attachment
#asset = ActiveStorage::Attachment.find_by(params[:id])
logger.debug "The value of #asset is #{#asset}"
#asset.purge
redirect_to #resource
end
I have a form that shows the resource and loops through the attached assets. Below is the snippet of code doing the loop through the assets:
<% #resource.assets.each do |asset| %>
<%= link_to 'Remove Attachment', delete_asset_attachment_resource_url(#resource, asset.id), method: :delete, data: { confirm: 'Are you sure?' } %>
<% end %>
The /resources page properly shows the resource along with the attached assets. However, when I try to click the link to delete one of the assets, I receive an error: "undefined method `purge' for nil:NilClass". However, in console I see the attachment exists.
Here is the output from the server console:
Started DELETE "/resources/10/delete_asset_attachment.18" for ::1 at 2019-03-09 17:27:28 -0500
Processing by ResourcesController#delete_asset_attachment as
Parameters: {"authenticity_token"=>"EFZO5V9Bii3dId0I6hn5DajFR5WJYZBc8qPAAi5ppQOFW3cws5I4FjyVP9IlvA+2a2kKUJhobnqd8atG4L3k+g==", "id"=>"10"}
Resource Load (0.1ms) SELECT "resources".* FROM "resources" WHERE "resources"."id" = ? LIMIT ? [["id", 10], ["LIMIT", 1]]
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 1], ["LIMIT", 1]]
ActiveStorage::Attachment Load (0.1ms) SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE (10) LIMIT ? [["LIMIT", 1]]
The value of #asset is #<ActiveStorage::Attachment:0x00007f8d7bd4df68>
ActiveStorage::Blob Load (0.2ms) SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = ? LIMIT ? [["id", 27], ["LIMIT", 1]]
Completed 500 Internal Server Error in 5ms (ActiveRecord: 0.6ms)
NoMethodError - undefined method `purge' for nil:NilClass:
::1 - - [09/Mar/2019:17:27:28 EST] "POST /resources/10/delete_asset_attachment.18 HTTP/1.1" 500 76939
http://localhost:3000/resources/10/edit -> /resources/10/delete_asset_attachment.18
Started POST "/__better_errors/70da0e976a425fce/variables" for ::1 at 2019-03-09 17:27:28 -0500
ActiveStorage::Blob Load (0.2ms) SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = ? LIMIT ? [["id", 27], ["LIMIT", 11]]
::1 - - [09/Mar/2019:17:27:28 EST] "POST /__better_errors/70da0e976a425fce/variables HTTP/1.1" 200 36499
http://localhost:3000/resources/10/delete_asset_attachment.18 -> /__better_errors/70da0e976a425fce/variables
I've searched for solutions everywhere. The couple that exist on stackoverflow didn't address my issue. There is an incredible lack of specific details and examples in the Rails guide or anywhere else on the web for specifically handling deleting attachments. Would appreciate any help.
UPDATE: Here are my routes.rb:
resources :resources do
get 'listing', :on => :collection
put :sort, on: :collection
member do
delete :delete_asset_attachment
end
end
UPDATE 2: rails routes output
resources GET /resources(.:format) resources#index
POST /resources(.:format) resources#create
new_resource GET /resources/new(.:format) resources#new
edit_resource GET /resources/:id/edit(.:format) resources#edit
resource GET /resources/:id(.:format) resources#show
PATCH /resources/:id(.:format) resources#update
PUT /resources/:id(.:format) resources#update
DELETE /resources/:id(.:format) resources#destroy
I've been able to make this work. Ahhhh. The rush, after hours of frustration.
Piecing things together after reading this article
Deleting ActiveStorage Attachments From the Controller, 3 Ways
I changed my controller code to be this:
def delete_asset_attachment
#resource.assets.find_by(params[:attachment_id]).purge
redirect_to #resource
end
and my form to be this:
<% #resource.assets.each do |asset| %>
<%= asset.filename %>
<%= link_to 'Remove Attachment', delete_asset_attachment_resource_url(#resource, asset.id), method: :delete, data: { confirm: 'Are you sure?' } %>
<% end %>
I believe the issue was that the line in my old code:
#asset = ActiveStorage::Attachment.find_by(params[:id])
...was only passing the #resource id and the attachment was not being found. The key was changing this line:
#resource.assets.find_by(params[:attachment_id]).purge
...which more properly points to the correct resource and then the specific asset (attachment) to be purged.
Fix the syntax of find_by and use safe ampersand, instead
#asset = ActiveStorage::Attachment.find_by(params[:id])
#asset.purge
try:
#asset = ActiveStorage::Attachment.find_by(id: params[:id])
#asset&.purge
The link_to in my user name is creating an error and I don't know why.
Error:
Couldn't find StripeAccount without an ID
Controller:
this is inside a separate controller from the StripeAccount controller
def settings
#user = current_user.id
#stripe_account = StripeAccount.find(params[:stripe_account_id])
end
I have tried "#stripe_account = StripeAccount.find(params[:id])" with the same error
View:
<%= link_to user_stripe_account_path(#user, #stripe_account) %>
I have tried using #stripe_account.id, etc.
Models:
stripe_account::
belongs_to :user, optional: true
user::
has_one :stripe_account
Routes:
resources :users do
resources :stripe_accounts
end
Error when i try loading the /settings page:
Here's the CMD from when I use: #stripe_account = StripeAccount.find(params[:stripe_account_id])
app/controllers/dashboard_controller.rb:18:in `settings'
Started GET "/settings" for 127.0.0.1 at 2018-11-17 06:27:04 -0500
Processing by DashboardController#settings as HTML
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 2], ["LIMIT", 1]]
↳ app/controllers/dashboard_controller.rb:17
Completed 404 Not Found in 3ms (ActiveRecord: 0.3ms)
ActiveRecord::RecordNotFound (Couldn't find StripeAccount without an ID):
app/controllers/dashboard_controller.rb:18:in `settings'
When i use #stripe_account = StripeAccount.find(params[:id])
ActiveRecord::RecordNotFound (Couldn't find StripeAccount without an ID):
app/controllers/dashboard_controller.rb:18:in `settings'
Started GET "/settings" for 127.0.0.1 at 2018-11-17 06:28:21 -0500
Processing by DashboardController#settings as HTML
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 2], ["LIMIT", 1]]
↳ app/controllers/dashboard_controller.rb:17
Completed 404 Not Found in 3ms (ActiveRecord: 0.3ms)
ActiveRecord::RecordNotFound (Couldn't find StripeAccount without an ID):
app/controllers/dashboard_controller.rb:18:in `settings'
What am i doing incorrectly?
The only issue i can think of that may be happening is rails/ruby is finding the API ID from stripe_account, which contains a bunch of information from stripe... if so, is there a way i can specifically state using the ID from the table?
You should be able to do #stripe_account = current_user.stripe_account if you wan't to set the variable to the current_user's stripe account (you have no id param on the request). And I recommend you to use #user = current_user or #user_id = current_user.id since it's confusing to read a variable named #user that has an integer value.
When you define "StripeAccount belongs_to User", by default (it's the convention) ActiveRecord looks for a user_id column on stripe_accounts table.
I'd recommend you to read this https://guides.rubyonrails.org/association_basics.html. It explains all types of associations and you can configure your associations even if they are not conventional (different class names, no _id column, etc).
After many attempts, i got one way to work. I'm not sure how efficient this is and i will explore more options.
This ended up working how i wanted to:
#stripe_account = StripeAccount.find_by(params[:id])
The key was using ".find_by" and not ".find". This allows the link_to to operate and goes to the right location.
So I want to pass a data from a view that was rendered from an external api to a controller to be able to save the ID to a model/database table.
This is my view:
<h1>Heroes</h1>
<% #response.each do |hero| %>
<div class = "hero_wrap">
<div class = "img">
<img src="https://api.opendota.com<%= hero["img"]%>", id ="hero_img"/>
</div>
<div class = "fave_container">
<%= link_to(image_tag('fave.png', class: "fave_img"), new_hero_path) %>
<%= hero["id"]%>
</div>
<div class = "hero_name">
<%= hero["localized_name"] %>
</div>
</div>
<% end %>
My controller:
# heroes_controller
class HeroesController < ApplicationController
def index
#response = HTTParty.get("https://api.opendota.com/api/heroStats")
end
def create
#hero= Hero.new(params[:id])
#hero.save
redirect_to #hero
end
end
Routes:
Rails.application.routes.draw do
get '/signup', to: 'users#new'
get 'pages/home'
resources :pro_players
devise_for :users
resources :heroes
resources :users
root 'pages#home'
end
My hero model doesn't contain anything yet, I just want to pick the hero id and save it to my database.
this is my web app
server log upon clicking the star icon with link:
Started GET "/heros?custom_hero_id=1&method=post" for 127.0.0.1 at
2018-10-15 09:20:53 +0800
Processing by HerosController#index as HTML
Parameters: {"custom_hero_id"=>"1", "method"=>"post"}
User Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
↳/home/don/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-
5.2.1/lib/active_record/log_subscriber.rb:98
Rendering heros/index.html.erb within layouts/application
Rendered heros/index.html.erb within layouts/application (42.2ms)
Rendered layouts/_header.html.erb (1.1ms)
Rendered layouts/_footer.html.erb (0.4ms)
Completed 200 OK in 770ms (Views: 83.3ms | ActiveRecord: 0.7ms)
Updated log:
Started POST "/heros?custom_hero_id=21" for 127.0.0.1 at 2018-10-15 10:13:17 +0800
Processing by HerosController#create as HTML
Parameters: {"authenticity_token"=>"PHDEXdDmPhPX+VdloU2y6yONY5HN5wI2lIfOaSbSKj9+RvTO5Ua3QPuTcreLZtGNDFPaSOXhDVyve6J69+1CQQ==", "custom_hero_id"=>"21"}
User Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
↳/home/don/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.1/lib/active_record/log_subscriber.rb:98
(0.2ms) BEGIN
↳ app/controllers/heros_controller.rb:9
Hero Create (0.4ms) INSERT INTO "heros" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id" [["created_at", "2018-10-15 02:13:17.032248"], ["updated_at", "2018-10-15 02:13:17.032248"]]
↳ app/controllers/heros_controller.rb:9
(42.3ms) COMMIT
↳ app/controllers/heros_controller.rb:9
Redirected to http://localhost:3000/heros/10
Completed 302 Found in 59ms (ActiveRecord: 46.9ms)
Started GET "/heros/10" for 127.0.0.1 at 2018-10-15 10:13:17 +0800
AbstractController::ActionNotFound (The action 'show' could not be found for HerosController):
The :id attribute is by default a auto-increment attribute of datatype integer which sets its value under the hood whenever a new instance of the model is created. There are several ways to override the its behavior or setting its value explicitly, but considering that you are fairly new to the technology I don't recommend those for you. Instead I recommend a simpler solution of using another attribute to store hero["id"]
Steps:
1) Generate a migration to create a new column(say custom_hero_id) in the heroes table
rails g migration add_custom_hero_id_to_heroes custom_hero_id:integer
and do rake db:migrate
2) Change
<%= link_to(image_tag('fave.png', class: "fave_img"), new_hero_path) %>
to
<%= link_to(image_tag('fave.png', class: "fave_img"), heroes_path(custom_hero_id: hero["id"]), method: :post) %>
3) Finally change your create action to below
def create
#hero= Hero.create(custom_hero_id: params[:custom_hero_id])
redirect_to #hero
end
Update:
Due to unknown reason, custom_hero_id isn't saving to the DB. Probably due to forbidden attributes error. Try changing it to
def create
#hero = Hero.new(hero_params)
if #hero.save
redirect_to #hero
end
end
private
def hero_params
params.permit(:custom_hero_id)
end
Do you want to store the hero id or it's name ?
I would advise to create a method in your heroe model. Something like
// heroe.rb
def save_api_heroes_to_db(response)
response.each do |hero|
unless hero[:localized_name].exists?
hero.create(id: hero[:id], name: hero[:localized_name], image: hero[:img])
end
end
end
This method will save the heroe id, name and image in your database (unless it already exists).
You just have to call it in your index method, in your heroe controller.
Hope that helps.
First post, so i'm a newbie in StackOverflow. I'm trying for several days to make appear a Return button on a page form but only on a specific one.
So, I was advised to use backlink to make it appears.
Here's my code from the form where I want the return button
<% if #backlink.present? %>
<div class="spacer30"></div>
<% if #backlink == 'infos' %>
path = membre_path(menu: 'infos')
<% end %>
<% end %>
<%= link_to "Retour", path, class: "btn-rounded btn-turquoise btn-small" %>
Here's my code controller
def edit
super do |user|
puts "TEST PARAMS BACKLINK #{params[:backlink]}"
#backlink = params[:backlink]
end
end
and my route's :
get 'change_password', to: 'users/registrations#edit'
put 'update' => 'users/registrations#update', :as => 'user_registration'
get 'edit_password', to: 'users/registrations#edit', :as => 'user_edit'
So i should have in my log my PUTS 'TEST PARAMS BACKLINK' but nothing appear, only :
Started GET "/change_password.1?backlink=infos" for ::1 at 2017-10-04 10:07:41 +0200
Processing by Users::RegistrationsController#edit as
Parameters: {"backlink"=>"infos"}
User Load (9.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
Rendering users/registrations/edit.html.erb within layouts/application
Rendered users/registrations/edit.html.erb within layouts/application (14.4ms)
Rendered shared/_navbar.html.erb (4.0ms)
Rendered shared/_flashes.html.erb (1.1ms)
Completed 200 OK in 231ms (Views: 217.0ms | ActiveRecord: 9.1ms)
Any ideas why it doesn't work?
Many thanks.
I just had to delete some lines, here's what i changed from my registration controller :
def edit
#backlink = params[:backlink]
super
end
This way, it appears exactly the way I wanted to.
Many thanks :)
I have the following in my routes.rb file:
match "/service/:product" => "products#show_name"
match "/products/custom/" => "products#custom"
match "/products/customform" => "products#customform"
match "/categories" => "products#categories"
match "/search" => "products#search"
match "/about" => "products#about"
get 'category/:tag', to: 'products#category', as: :tag
resources :products do
resources :reviews
end
I am trying to access the url "/service/birchbox". When I do, I get an error saying
No route matches {:action=>"edit", :controller=>"products"}
Any advice on how to fix this? I am trying to get this url to go to the first route listed (to the controller products#show_name but is going to edit for some reason).
Here is some more information I'm seeing in the console. It seems like it's going to show_name but I keep getting an error.
Processing by ProductsController#show_name as HTML
Parameters: {"product"=>"birchbox"}
Product Load (0.2ms) SELECT "products".* FROM "products" WHERE "products"."slug" = 'birchbox' LIMIT 1
(0.1ms) SELECT COUNT(*) FROM "reviews" WHERE "reviews"."product_id" = 14
ActsAsTaggableOn::Tag Load (0.1ms) SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" = 14 AND "taggings"."taggable_type" = 'Product' AND (taggings.context = 'tags' AND taggings.tagger_id IS NULL)
Rendered products/show_name.html.erb within layouts/application (97.3ms)
Completed 500 Internal Server Error in 164ms
ActionController::RoutingError (No route matches {:action=>"edit", :controller=>"products"}):
app/views/products/show_name.html.erb:42:in `_app_views_products_show_name_html_erb___2110533700820522490_70197663436420'
It seems that in views/products/show_name.html.erb at line 42 you have something like this:
<%= edit_product_path %>
And this route doesn't exist. edit route requires product id. Try this:
<%= edit_product_path(#product) %>