rails 5 routing, PUT action winds up as GET - ruby-on-rails

using acts_as_votable gem to upvote/downvote a "skill",
rails 5.0.0 app
routes.rb:
resources :skills do
member do
patch "upvote", to: "skills#upvote"
put "downvote", to: "skills#downvote"
end
end
skills controller:
def upvote
#skill.upvote_from current_user
redirect_to skill_path(#skill.id)
end
def downvote
#skill.downvote_from current_user
redirect_to skill_path(#skill.id)
end
the view:
<%= link_to "Up Vote", upvote_skill_path(skill), method: :put %>
generates this HTML:
<a rel="nofollow" data-method="put" href="/skills/98/upvote">Up Vote</a>
but when clicking the link, somehow its a GET:
Started GET "/skills/98/upvote" for 192.168.0.2 at 2017-02-23 22:46:07 -0500
ActionController::RoutingError (No route matches [GET] "/skills/98/upvote"):
'rake routes' output looks right:
upvote_skill PUT /skills/:id/upvote(.:format) skills#upvote
downvote_skill PUT /skills/:id/downvote(.:format) skills#downvote
Im at a loss.. the only thing I can think is this app started life out as an API only app http://edgeguides.rubyonrails.org/api_app.html but I am pretty sure I have followed all the convert "regular app to API" steps by doing section 3.2 backwards. But maybe I am missing something ?

Rails uses unobtrusive javascript to perform this type of actions, probably you don't have included the javascript correctly, because your app started as api-only and assets and views are not included in this mode.
In your application.html.erb ensure you are including the javascript
<!-- app/views/layouts/application.html.erb -->
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
You application.js must have at least these definitions
// app/assets/javascripts/application.js
//= require jquery
//= require jquery_ujs
finally, the Gemfile needs
gem 'jquery-rails'
Then: bundle, reload the server and test again.

Related

Unable to get "delete" link to work on an admin panel in Ruby on Rails

I am new to Ruby On Rails and am currently creating standard CRUD operations for an admin panel I am building manually within the app (no admin gems used).
However, When I call a delete link on my show.html.erb page nothing happens (no error screen or any other feedback in the browser). Javascript is fully enabled and I believe I have the correct gems installed.
Could someone please let me know the best way to remedy this? I will link all relevant files below:
app/views/admin/posts/show.html.erb
<h1><%= #post.title %></h1>
<p><%= #post.body %></p><br>
<%= link_to "delete", [:admin, #post], method: :delete %>
controllers/admin/posts_controller.rb
class Admin::PostsController < Admin::ApplicationController
def index
#post = Post.all
end
def show
#post = Post.friendly.find(params[:id])
end
def new
#post = Post.new
end
def create
post_params = params.require(:post).permit(:title, :body, :slug)
#post = Post.new(post_params)
#post.save
redirect_to [:admin, #post]
end
def destroy
#post = Post.friendly.find(params[:id])
#post.destroy
end
end
app/assets/javascripts/admin.js
// 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, or any plugin's
// vendor/assets/javascripts directory 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
// compiled file. JavaScript code in this file should be added after the last require_* statement.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require rails-ujs
//= require activestorage
//= require turbolinks
//= require_tree .
//= require jquery
//= require jquery_ujs
app/assets/stylesheets/admin.css
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's
* vendor/assets/stylesheets directory can be referenced here using a relative path.
*
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
* files in this directory. Styles in this file should be added after the last require_* statement.
* It is generally better to create a new file per style scope.
*
*= require_tree .
*= require_self
*/
app/views/admin/admin.html.erb
<!DOCTYPE html>
<html>
<head>
<title>JonBlog</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag 'admin', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'admin', 'data-turbolinks-track': 'reload' %>
</head>
<body>
<%= yield %>
</body>
</html>
Console output when 'delete' clicked.
Started GET "/admin/posts/spiral" for 127.0.0.1 at 2018-10-03 23:43:48 +0100
Processing by Admin::PostsController#show as HTML
Parameters: {"id"=>"spiral"}
Post Load (0.2ms) SELECT "posts".* FROM "posts" WHERE "posts"."slug" = ? LIMIT ? [["slug", "spiral"], ["LIMIT", 1]]
↳ /Users/jonathonday/.rvm/gems/ruby-2.3.1/gems/friendly_id-5.2.4/lib/friendly_id/finder_methods.rb:60
Rendering admin/posts/show.html.erb
Rendered admin/posts/show.html.erb (1.0ms)
Completed 200 OK in 18ms (Views: 12.2ms | ActiveRecord: 0.2ms)
routes.rb
Rails.application.routes.draw do
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
namespace :admin do
resources :posts
end
resources :comments
end
Notice that the route getting hit is a GET request, and you are hitting the show action. If you inspect the HTML of the page I'll bet it says nothing about the delete method. So the link_to call as written must not be passing :method correctly.
I'm a little out of practice, but what happens if you try something like link_to("Delete", admin_post_path(#post), method: :delete) (that is, using a string url instead of array for domain/resource specifier)?

How to serve image assets from an Engine in a Rails app

I'm having trouble getting image assets in my engine to render inside the host app.
My host app is capable of grabbing css and javascript from then engine thanks to code like this in the view/layout/application.html.erb file:
<%= stylesheet_link_tag 'my_engine/application', :media => 'all' %>
<%= javascript_include_tag 'my_engine/application' %>
However, I don't know of a similar method for including the images from my engine. Any ideas on how I can get the engine's image files to render in the host app?
Edit:
In my engine's engine.rb file, I've added the images directory to the app's directory like this:
initializer :assets do |config|
Rails.application.config.assets.paths << root.join("app", "assets", "images", "my_engine", "some_subdirectory")
end
and the view has an image tag that looks like this:
<%= image_tag "/my_engine/some_subdirectory/picture.png" %>
but my server logs, I see this:
Started GET "/assets/some_subdirectory/picture.png" for 127.0.0.1 at 2014-04-06 20:11:38 -0500
Served asset /some_subdirectory/picture.png - 404 Not Found (3ms)
ActionController::RoutingError (No route matches [GET] "/assets/some_subdirectory/picture.png"):
You don't need to do this at all because Rails does it for you:
initializer :assets do |config|
Rails.application.config.assets.paths << root.join("app", "assets", "images", "my_engine", "some_subdirectory")
end
Instead, you can reference the images exactly the same way as you would as if they were in the application:
<%= image_tag "your_image.jpg" %>
I'm assuming here that your_image.jpg is at /app/assets/images/your_image.jpg within your engine. If it's in a subdirectory, then:
<%= image_tag "subdirectory/your_image.jpg" %>
There's no need to include the name of your engine in the path unless the file is at some place like app/assets/images/your_engine/your_image.jpg, in which case:
<%= image_tag "your_engine/your_image.jpg" %>
Would be the correct way to do this.
The Engines Guide contains more useful information about engines too.

link_to confirm, no matter the answer will always execute the action

When I press the link, the confirmation pops up, but no matter if I answer Yes or No, it will always execute the action and delete the record.
View:
link_to "Remove", gamep, :method => :delete, :confirm => "Remove "+#player.name+" from "+gamep.game.title+"?"
Action:
def destroy
#gameplayer = GamePlayer.find(params[:id])
#gameplayer.destroy
respond_to do |format|
format.html { redirect_to #gameplayer.player }
end
end
Yes I have
javascript_include_tag :defaults
Edit:
I had to fix this originaly using a jquery.rails.js because the :delete method wasn't working. Without this, there is no confirmation, and the link_to just acts like a normal link.
For some reason, when I installed the 'jquery-rails' gem, it didnt put a 'jquery-ujs.js' in my 'public/javascripts' folder.
C:/Ruby192/lib/ruby/gems/1.9.1/gems/jquery-rails-1.0.16
C:/Ruby192/lib/ruby/gems/1.9.1/gems/rails-3.1.1
application.js
// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults
//= require jquery
//= require jquery_ujs
//= require_tree .
In Rails 3.1, you should be using "application", not "defaults", otherwise none of your javascript will get loaded properly:
javascript_include_tag "application"
Also, you don't need to manually include any additional javascript files, as the application manifest (app/assets/javascripts/application.js) will already pull them all in. Just make sur e*all* of your JS files are sitting in app/assets/javascripts, not 'public/javascripts`.
And make sure you are not using the rails.js file from previous versions of Rails. This has been replaced by the jquery-rails gem in Rails 3.1.

Trying to call methods from gems in a view, getting "no such file" error

I have just installed a base installation of rails and have edited the main page to view some basic html and a link to create a new blog post via ruby in the corresponding 'erb' file. I am trying to add some additional ruby commands on this same page via <%= %> tags.
<h1>Hello, Rails!</h1> <%= link_to "My Blog", posts_path %>
<p>
<%= require 'rubygems' %>
<%= require 'simplegeo' %>
<%= SimpleGeo::Client.set_credentials('token', 'secret') %>
<%= a = SimpleGeo::Client.get_context(coordinates,coordinates); a %>
</p>
When I load this page , I get the following error: no such file to load -- simplegeo
Can someone point me in the right direction? Many thanks!
In Rails 3, you need to add this gem to your "Gemfile" .. follow this: http://gembundler.com/rails3.html
Remove this completely.. Never do this in your views
<%= require 'rubygems' %>
<%= require 'simplegeo' %>
Once you restart your rails server, if you added "simplegeo" to your gemfile, it'll be auto-required.
Move this to your controller to start
SimpleGeo::Client.set_credentials('token', 'secret')
#simple_geo_client = SimpleGeo::Client.get_context(coordinates,coordinates)
Then in your view, you can access any variable that starts with #
To get started in Rails, check out http://railsforzombies.org/
In rails 3.x, you use Bundler to specify gems. No need to require, especially in views.
Correct way is:
Open Gemfile
Set/List required gems inside using format:
source :rubygems
gem "simplegeo"
gem "some_other_gem"
Run bundle install (or just bundle) command in console.
now restart your server and gems are auto required.
Check out Rails guide on how to start.
Most probably you did not install Simplegeo gem properly, or did not attach it correctly in you IDE.

Rails: link_to with :remote => true not working

I'm trying to implement a voting system kind of like the one here on Stack Overflow. (Using Rails 3) I want the voting to be done without a page reload, so I have this code
link_to("/tags/#{tag.id}/upVote", :remote => true )
And so in my /views/tags directory I have a file called _upVote.js.erb that I thought would be called when this link is clicked, but it is not. It is trying to process upVote as HTML and this is the error I get
Missing template tags/upVote with {:formats=>[:html]
Also, here is what I have in my routes file
match "tags/:id/upVote" => "tags#upVote"
Any ideas how I can get this to work?
If you got this error message in a blank new page, that means that your remote call does not work and the call wasn't made via an Ajax request. You need to check that your layout correctly loads jQuery and the jQuery Rails connector available here : http://github.com/rails/jquery-ujs
Then use Firefox+Firebug to check that the call is really an Ajax call.
I had this same problem.
To resolve the problem, I followed
https://launchschool.com/blog/the-detailed-guide-on-how-ajax-works-with-ruby-on-rails
Rails 4 rendering a partial with ajax, jquery, :remote => true, and respond_to
And finally, I had to
Require both jquery and jquery_ujs were in the application.js manifest.
//= require jquery
//= require jquery_ujs
After all that, Rails ajax started working for me.
See this post for a solution:
Rails form_for :remote=>true is not calling js method
When changing the rails environment to JQuery, you may accidentally lose your jquery-ujs file.
type something like inside your rails application root:
rails g jquery:install
And then, inside your application.html.erb add the line
<%= javascript_include_tag :defaults %>
or explicitly (do not forget to include your jquery separately):
<%= javascript_include_tag :rails, :application %>
[EDIT: for Rails 3.1 or greater using the asset pipeline]
Use the gem jquery-rails (as mentioned above) and add the following lines to the app/assets/javascripts/application.js (if they are not there already) :
//= require jquery
//= require jquery_ujs
Hope this helps!

Resources