按鍵執行function和其他問題


#1

版上各位先進大家好,我也是個新手
先說聲抱歉,標題取這麼長,因為脫離教材後才發現問題真的很多。

最近嘗試想做一個可以建立博客來書單的網站,希望可以用來分享書單堆坑用(?

架構如下:
每個User可以建立很多的List ( one-to-many), 每個List(書單)會有許多的Book, 而Book可能會出現在多個List中 (many-to-many)
架構已大致完成。

但現在卡在一個功能上:
我要在List的show page上建立一個單格的表單。
使用者在表單輸入想要在博客來網站上查尋的書名的關鍵字後,按下按鈕後執行我寫好的爬蟲程式,程式回傳列出符合結果的書名的待選清單。使用者從待選清單中選好特定的書後,這個書名(也就是一個Book物件)就會加到List show page的清單中

爬蟲程式: https://gist.github.com/iansrc0811/fcf62a3640537c21afac2a37c24d7ba5
需要輸入字串當參數

查了好久的文件和stackover flow,還是搞不懂要如何實做。希望可以得到一些方向

問題:
1.我的爬蟲程式要怎麼被呼叫和放在哪裡比較好,可以把方法拿出來直接放在application_helper.rb嗎?
2. 我要怎麼建立form? 好像form_for和form_tag都不太對,因為我只是想要取得input,並執行一個跟model都沒關的程式。還是一般的html就可以了?
3. 建立好form後,我要怎麼取得輸入的文字,並傳入爬蟲程式的function當參數?
4. 如何讓按鈕可以跑寫好的爬蟲程式,並使用form的input當參數
大概像是: <%= link_to “送出”, function_name(input_string), class: “btn btn-xs btn-primary” %>
5. 接上一點,表單送出後,可以先render出一個醜醜的頁面,讓使用者選好書名後再連回List show page。
我知道要好看一點要做到AJAX的功能(有錯請指正),類似google search的表單,
例如我在form輸入 “ruby” , 在form下方就自動出現我爬出來的書名清單,我選定書名後,按「確認」鈕,建立book物件存入database,完成操作。
以上的問題很多,我卡了好久,還請各位先進不吝指教。
謝謝各位。


#2

以我的知道的給一些建議,請後人再修正,簡單起見,先不講AJAX

1 自己寫的東西應該放到lib,又因這是跟資料有關的,所以應該放在lib/model

接下來在application.rb裡加入load路徑
config.autoload_paths << Rails.root.join('lib/model')
這樣你就可以在controller裡使用這個model了

2 我應該會用form_tag吧!路徑和method要設定好,接著打routes

<!-- xxx.html.erb -->
<%= form_tag('/search_book', method: :get) %>
# routes.rb
get 'search_book' to 'search#search_book'
# app/controllers/search_controller.rb
class SearchController < ApplicationController
  def search_book
    input = params[:query]  # 可以拿到form裡的使用者輸入值
    # ===== call your Crawler here =====
    Crawler.new.get_book_names(input)
    dealing data...
    # ============================
   render 'show_result'
  end
end
<!-- app/views/search/show_result.html.erb -->
這裡打你要顯示給用戶的內容

3 建好form後,裡面至少應該要有一個text_field,這樣送出表單時就會把該參數送出了
<input name="query" type="text" value="" placeholder="請輸入書名" />

4 你那個的寫法像是寫在前端,那你要寫一個前端的爬蟲,而不是後端的爬蟲,你的form用一般http送出,等待回應即可,而且你已經寫form了,用submit button就行啦~

Anyway,方法很多種,這只是最基本的一種


#3

針對這個話題,順便講一些技術外的東西

首先,單純的 Proxy 從 A 直接接 B 站問題很多,類似 B 站可以餵假資料給 A 站,就會知道 A 站是否有接 B 站的資料之類的,且即時接的話,B 站倒了或是阻擋 A 站,A 站會倒掉的

這事件當時很有名,也很有趣,所以從來都不建議『即時接』,而是定時全掃全爬,使用者有需求時從 DB 直接出唄,真的沒有的話才用輔助的方式給使用者之類的,類似希望他能複製貼上別人家的東西到本站來,有的沒的

討論完道德後,接下來是技術問題

  1. 新手教學有教你寫純 Ruby,還有把自己寫的 Ruby 放到 Rails 的 lib 下的方法,這東西是你自己寫的外掛程式,和 Rails 無關,所以它本身應該能"獨立運作"(類似在 irb 引入它就可以直接打了),然後把它放進 Rails 的流程即可(類似在 model 內使用它)

  2. 你可以嘗試不用 Rails 的 helper 全打純 HTML 完成你的目的會好點,單純 Rails 需要 CSRF token,所以非 GET 的需求送出時要記得包含就好

  3. 這是 JavaScript 的問題了…新手教學後面有教你基本的 jQuery 用法才是,真的不會寫的話再提出來

  4. 這邊同 (2 & 3) 這是純 JavaScript 的問題,你可以把 Rails 當作接受需求和發送結果,然後接 JS 來用 AJAX 和 Rails 溝通哩

  5. 寫個簡單的順序給你好了,『 HTML表單 => 使用者輸入 => 按下送出 => jQuery 取得所有資訊,包成 Object, 用 AJAX 送給 Rails,順便弄個轉圈圈的畫面給使用者看 => Rails 回 AJAX 的結果,JavaScript 接到後顯示給使用者確認,並把隱藏 id 塞回 form 中 => 二次送出 => 完成 』

不管如何好好的練一下 CSS / JavaScript,如果你感覺卡,就是你有缺技術債,Rails 開發從來都不只有 Rails 而已,外部的比重會佔 80% 以上唄,Rails 可能低於 20%,所以從你的問題來看,應該先去補足其它方面的知識就是了,真的卡住了就拿你的 code & log 來問唄


#4

謝謝兩位前輩的回覆
我會努力補足技術債的
教學影片真的很有料,收獲許多。

目前還是卡一些bug不過就還是先自己解決吧 :slight_smile: