動態一對多表單建立

A…已經有 demo code 了,自己去玩唄 : P

https://github.com/JokerCatz/RailsDemoHasMany

這邊其實是結合新手教學中,JavaScript 的動態表單製作那邊配 Rails 儲存的方式而已
其中一個小部分講解一下,HTML 中,form 內會被送出的只有有 name 這個 attribute 的 field 而已,其餘的都不會送出,看懂這個其他就是 event 和操作方式而已了 & 這個編輯的 view 無法製作分頁,如果要分頁編輯的話就還需要再多些值之類的(類似此頁的開始與結束的ID)

& 無聊的話建議還可以上 sortable ,類似

https://jqueryui.com/sortable/

把 id 帶回,把 params 的 array 的 index 當作 position,顯示用 position 排序,就可以很漂亮之類的
還可以再配上Ajax,不過 event & route 都還要再多些, form 可以用 jQuery serialize 的方法變成網址再傳出…再寫下去就多了

anyway 事情可以很單純,也可以很複雜,但對我而言,能做出心中想要的東西比較重要些就是

1個讚

請問JC大,

為什麼這邊要加first?

> ic = ItemChild.where(:item_id => @item.id , :id => id).first

因為透過where方法,return的是一個Array型態的資料,所以透過first會取到第一個element。

ㄟ… 那第二筆資料怎麼辦?:sweat:

你先看看Array這個資料結構,應該就會使用了
http://ruby-doc.org/core-2.2.3/Array.html#class-Array-label-Accessing+Elements

…請問一下

@item = Item.find(params[:id])
@item = Item.where(:id => params[:id]).first

有何不同?基本上 SQL 是一樣的,不同點在於前者找不到的話會噴 404,後者不會噴 404,如果找不到的話會直接回傳 nil

做的東西不就是多筆?,外面不就是一個 Array 然後 each 跑裡面的 code 了?可能會多 select 不過看得懂為主

不好意思,我問的不清楚。
我的問題是,為什麼只要叫第一筆資料出來?

我今天要修改的資料類似

set = {1 => {:name => 'test'} , 2 => {:name => 'yoo'} ...... } #可能超過1k筆

key 為 id,set 為 N 筆資料,而我可以寫成這樣的結構比較容易了解(看不懂 each_pair 的話去看 Hash 的 doc,否則一切白談)

set.each_pair do |id , update_data|
  #item = Item.find(id) #用這個會噴404 Exception,後面會全中斷
  item = Item.where(:id => id).first #不會404,找不到會是nil
  if item #如果nil則跳過
    item.update_attribute(update_data)
  end
end

結構就這樣而已,而不是 Rails scaffold 教你的每次只能改一筆資料,那樣很蠢…

所以

[一堆資料].each_pair do |其中一筆的id , 那筆資料要修改的值|
  item = Item中尋找(其中一筆的id).的第一筆 #而非一定要找到
  如果有該筆 item
    修改 item.update成(那筆資料要修改的值)
  結束
結束

這樣還看不懂? & 我上面也有說了

Item.find(id)
Item.where(:id => id).first

基本上結果是一樣的,如果 Item 內有該 id 的話,但沒有 id 的話結果會完全不一樣,你自己玩玩看應該就知道我的意思的

對集合操作來說,通常還是一筆一筆操作,而不是一次修改一個集合,畢竟集合內是由個體組成,而另外一方面這世界沒有那麼剛好全都有資料,而你也該學一下什麼是 Exception 或例外處理方式,find會噴,first不會噴會是nil,唸起來的語意完全不重要,而是你想達成什麼目的,你是在寫程式而非寫文章,以上

所以,如果找不到第一筆,它噴出nil就停了, if params[:ic_old]就執行結束了,但是不會出現404。

那如果找到第一筆後,它會接著找第二筆嗎?然後一路找到最後一筆去?

不好意思,一直問蠢問題…

hmm~ 沒差,那邊的意思是找不到就略過而已,find 找不到的話會直接吐 404 而不會略過

> <li class="template">name<input data-name="ic[name][]"> , age<select data-name="ic[age][]"><%= options_for_select(age_list) %></select><span class="add">add</span><span class="del">del</span></li>

試了好久,還是沒辦法把radio button弄上去,可以麻煩JC大再弄個範例嗎?

okay晚點哩

感恩!!期待範例!!!

先問個簡單的問題,
如果把JC大的multi.html.erb裡面的code複製貼上,但是jQuery的部分沒有反應,
是因為我少灌或多灌了甚麼東西嗎?

單純你的 layout 和我的 layout 長得不一樣,我的 layout 裡面有個類似

<%= yield :header %>

而我的 view 內有個

<% content_for :header do %>
  ..
<% end %>

簡單的來說就是 view 內的某段 code 要放在 layout 內的某個地方的意思,我都稱之為挖洞之後丟東西進去,其實在 youtube 的 RailsFun.tw 教學裡面有…

有阿,我知道RailsFun.tw 教學裡面有。
我也在我的layouts/application.html.erb理面加上了,可是我> <ol></ol>裡面都是空白的。

> <html>
> <head>
>   <title>Surveysays</title>
>   <%= stylesheet_link_tag    'application' %>
>   <%= javascript_include_tag 'application' %>
>   <%= yield :head %>
>   <%= csrf_meta_tags %>
> </head>

multi.html.erb

> <h1>Multi : <%= current_user.name %></h1>

> <%= form_tag multi_save_dashboard_user_path do %>
>   
>   <ol>

>    <% @question.each do |question| %> 
>    <% @answer = question.answer %>
>   
>      
>     <li class="template">
>        <%= label_tag question.id %>  
>        <%= label_tag question.content %>
>        <select data-name="ic[age][]"><%= options_from_collection_for_select(@answer, :id, :content) %></select>
>         <span class="add">add</span><span class="del">del</span>
>     </li>
>     
>    
>    
>     <% end %>
>   </ol>
>   <button type="submit">Submit</button>
> <% end %>
jQuery(function($){
  bind_item($('ol li'));
  if($('ol li').length === 1){ //only template
    $('ol li .add').click();
  }
});

…你真的該從頭開始練 jQuery … 所以這邊一定要有 template 那段,沒有的話就沒辦法複製自己,或是你的對象錯誤之類的,你可以嘗試"除錯",類似

console.log($('ol li'));

and 可以的話請先去撞牆一陣子才來問,而不是一直想來問解答之類的,用肉體記得 bug 的發生的原因和自己解決的方式,與尋找答案,也是學習的必經過程就是

而很多時候你排除掉 Rails 從最基本的 HTML / CSS / JavaScript / jQuery 開始練,反而會更專心些,如同我在新手教學那樣一樣,確認 ok 了,才來套 Rails 唄

好的,我知道了。感恩~