1

I have view with two forms and I am trying to submit a form with a link to a controller that has an action. But when I try to submit it to it look for the action in my other controller. I tried using parameters in a different way and it did not work. I know something is wrong with my routes file but I do not understand what, as I am new to Rails. Also I am using Rails 5 if it helps.

Edit: the second form is the one that is failing.

Error:

No route matches {:action=>"scrape", :controller=>"links_to_be_scraped"}

View:

<%= form_for WatchedLink.new, url: {action: "create"}, html: {class: "links_to_be_scraped"} do |f| %>
  <%= f.text_field (:link) %>
  <%= f.submit "Save" %>
<% end %>
<% @url = 'default' %>
<%= form_for @url, url: {action: "scrape"}, html: {class: "page_scraper"} do |f| %>
  <%= f.text_field (:url) %>
  <%= f.submit "Scrape" %>
<% end %>

Controller:

class PageScraperController < ApplicationController
    require "nokogiri"
    require "open-uri"
    require "diffy"
    require 'htmlentities'

    def scrape

        @url = params[:url]

        page = Nokogiri::HTML(open(@url)).to_s
        coder = HTMLEntities.new
        encodedHTML = coder.encode(page)
        puts page

     end

end

routes.rb

Rails.application.routes.draw do
  root 'links_to_be_scraped#index'

    resources :page_scraper do

        member do
            get :scrape
        end
    end 

    resources :links_to_be_scraped do

        member do
            get :delete
        end
    end



end

routes console

       Prefix Verb   URI Pattern                               Controller#Action
                      root GET    /                                         links_to_be_scraped#index
       scrape_page_scraper GET    /page_scraper/:id/scrape(.:format)        page_scraper#scrape
        page_scraper_index GET    /page_scraper(.:format)                   page_scraper#index
                           POST   /page_scraper(.:format)                   page_scraper#create
          new_page_scraper GET    /page_scraper/new(.:format)               page_scraper#new
         edit_page_scraper GET    /page_scraper/:id/edit(.:format)          page_scraper#edit
              page_scraper GET    /page_scraper/:id(.:format)               page_scraper#show
                           PATCH  /page_scraper/:id(.:format)               page_scraper#update
                           PUT    /page_scraper/:id(.:format)               page_scraper#update
                           DELETE /page_scraper/:id(.:format)               page_scraper#destroy
delete_links_to_be_scraped GET    /links_to_be_scraped/:id/delete(.:format) links_to_be_scraped#delete
 links_to_be_scraped_index GET    /links_to_be_scraped(.:format)            links_to_be_scraped#index
                           POST   /links_to_be_scraped(.:format)            links_to_be_scraped#create
   new_links_to_be_scraped GET    /links_to_be_scraped/new(.:format)        links_to_be_scraped#new
  edit_links_to_be_scraped GET    /links_to_be_scraped/:id/edit(.:format)   links_to_be_scraped#edit
       links_to_be_scraped GET    /links_to_be_scraped/:id(.:format)        links_to_be_scraped#show
                           PATCH  /links_to_be_scraped/:id(.:format)        links_to_be_scraped#update
                           PUT    /links_to_be_scraped/:id(.:format)        links_to_be_scraped#update
                           DELETE /links_to_be_scraped/:id(.:format)        links_to_be_scraped#destroy
Padu
  • 99
  • 9
  • I understand the first `form_for` needs to submit to `LinksToBeScrapedController#create` action and the latter `form_for` to `PageScraperController#scrape` action? In that case, by looking at your routes, switch `url: {action: "scrape"}, html: {class: "page_scraper"}` in the last form_for to `url: scrape_page_scraper_path(page_scraper_object)` and tell us what happens? Maybe this helps: https://stackoverflow.com/a/13578844/1677069 – Andres Feb 12 '18 at 15:09
  • Yes you understood what I am trying to do and I have also changed the code like you suggested and now I get this error: `undefined local variable or method page_scraper_object' for #<#:0x00007f56e8fa25a8> Did you mean? page_scraper_path` – Padu Feb 12 '18 at 15:18
  • I have also changed it to `url: scrape_page_scraper_path(page_scraper_path)` and I get this `No route matches {:action=>"show", :controller=>"page_scraper"} missing required keys: [:id]` – Padu Feb 12 '18 at 15:22
  • If you have a route with GET-method, then this route needs a corresponding model-object as an argument (otherwise it doesn't know which object to show (GET method is used for #show actions for example)). If you really want to use GET then you have to provide the route with corresponding object (replace `page_scraper_object` with the name of your corresponding object). If you don't want to use GET-method (which I assume you don't because you have a form and I guess you want to post it to controller method), then change `get :scrape` inside your routes file to `post :scrape`. – Andres Feb 12 '18 at 15:23
  • I suggest to have a look on [non-resourceful routes](http://guides.rubyonrails.org/routing.html#non-resourceful-routes) more thoroughly because at the moment it looks more like a trial-and-error method. It looks like quite your case in the link. – Andres Feb 12 '18 at 15:27
  • I changed the routes file like you suggested and the form to `form_for @url, :url => {:controller => "page_scraper", :action => "scrape"} do |f|` and now I get `No route matches {:action=>"scrape", :controller=>"page_scraper"} ` I will start reading from that link you provided. – Padu Feb 12 '18 at 15:45
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/164978/discussion-between-andres-ehrenpreis-and-padu). – Andres Feb 12 '18 at 15:53

1 Answers1

2

As you don't want to make a GET-request on your form-submit then you should define the scrape-route as POST (or PUT or PATCH, whatever suits your needs the most, to clarify, maybe this stackoverflow post and rails-guide helps).

Because you currently don't have a specific page_scraper object to give to the scrape_page route then remove the member-block completely and define the page_scraper route separately as custom-route. Something like this:

resources :page_scraper
post 'scrape_page', to: 'page_scraper#scrape'

instead of

resources :page_scraper do
  member do
    get :scrape
  end
end

(/page_scraper/:id/scrape VS /page_scraper/scrape)

After that you should be able to change your form header to something like this:

form_for @url, url: {controller: 'page_scraper', action: 'scrape'} do |f|

For it is a case of non-resourceful routing then this is a good place to get a clear picture of how it should be defined: http://guides.rubyonrails.org/routing.html#non-resourceful-routes

Andres
  • 2,099
  • 3
  • 22
  • 39