一些ruby on rails學習上的小筆記:
Rails Controller
Params
全部通過
params.require(:post).permit!
只接數特定的 post 參數
@tweet = Tweet.create(params.require(:tweet).permit(:status)) @tweet = Tweet.create(params.require(:tweet).permit([:status, :location]))
permit Array
.permit(:category_ids => []) .permit({:locations => []})
render 和 redirect
render
render :new # render new.html.erb render action: 'new' # 同上 render text: Rails.env # 輸出純文字 render json: @files, status: 200 # same as => status: :ok render json: user.errors, status: 422 # return Http status code render json: episode, status: :created, location: episode # :created 等同 201 (新增成功)
redirect_to
redirect_to root_path redirect_to post_comment_path(@post, @comment) redirect_to @user, notice: 'Updated' # 等同 flash[:notice] = 'Updated' 再 redirect redirect_to(:back) # 回送出時的那一頁 redirect_to request.referer + "#user-#{@user.id}" # back + anchor 是無效的, 必須改成這樣 redirect_to(request.env['HTTP_REFERER']) # 效果同上 redirect_to action: 'profile' # 等同 redirect_to profile_path redirect_to root_path, :anchor => "user-#{user.id}" # url 加入 anchor : http://xxxxxx.com/#user-33
member VS collection
:member
如果要帶上原物件的id用member,member 的 prefix 必須要帶參數
/products/5/add_to_cart
<== 網址會有參數 ( 5 )
add_to_cart_product_path(@product)
所以可以在 controller 裡面用 params[:id] 來取得參數值
@product = Product.find(params[:id])
來找到特定的某一筆資料
resources :users do member do get :find end # 或簡寫成 get :find, :on => :member end
find_user_path(@user),會產出 user/23/find
通常用於對『單筆』資料做操作,像是
- show 只列出某個商品頁
- edit 只對某個商品做編輯
- update 只對某商品做資料更新
- delete 將某商品資料刪除
- add_to_cart 只對某筆商品加入購物車
:collection
如果只是一般頁面用collection,collection 的 prefix 可以不用帶參數
resources :users do collection do get :find post :freeze end # 或簡寫成 get :find, :on => :collection post :freeze, :on => :collection end
通常用於『複數資料』、『無資料』的情況下操作,像是
- index 所有商品列表
- new 新商品頁 (admin/products/new)
- checkout 購物車商品結帳
- clean 清空購物車
routes其他寫法
Restricting routes with except
resources :zombies, except: :destroy
Restricting routes with only
resources :zombies, only: :index
Restricting routes with multiple actions
resources :zombies, only: [:index, :show] resources :humans, except: [:destroy, :edit, :update]
Assets Helper
<%= javascript_include_tag "custom" %> <%= stylesheet_link_tag "style" %> <%= image_tag "rails.png" %>
Form helper
radio_button
<% UserDomain.domains.each do |k, v| %> <div> <%= radio_button_tag 'user[domain]', v %> <%= label_tag "user_domain_#{v}", t("domain.#{k}") %> </div> <% end %> radio_button("post", "category", "rails") radio_button("post", "category", "java") f.radio_button :decomp, 'fresh', checked: true f.radio_button :decomp, 'rotting' f.radio_button :decomp, 'stale' collection_radio_buttons(:item, :owner_id, Owner.all, :id, :name)
select
f.select :location, User.location, {}, { class: 'selectpick', data: { width: '80%'} } f.select :decomp, ['fresh', 'rotting', 'stale'] f.select :decomp, [['fresh', 1], ['rotting', 2], ['stale', 3]] s.select :profile_edit_flag, [['已修改', true], ['未修改', false]] select_tag "people", options_from_collection_for_select(@people, "id", "name") > 產生: <select id="people" name="people"><option value="1">David</option></select>
collection_select
User has_many UserLocation, 將 User 住的 Location 每項以 Select 列出來
current_user.user_locations.each do |l| collection_select('user_locations', '', UserLocation.locations_i18n, :last, :first, { include_blank: false, selected: l.location }, { class: 'location', id: nil } ) end
- 第一個參數 : HTML name 名稱
- 第二個參數 : user_locations[第二個參數], 我將它留空變成 array :
user_locations[]
- 第三個參數 : Hash (key: value)
:last, :first
: 會讓 hash 的 key 顯示在 option 的名字, hash 的 value 則是 option 的值include_blank
: 一定要設定它, 否則 class, id 不會 workselected
: 如果去掉, 就是未選擇的<select>
備註
1) f.collection_select(:category_id, Category.all, :id, :name) 等於 f.select :category_id, Category.all.map{ |c| [c.name, c.id] } 2) s.select :recommended, options_for_select(Translator.recommendeds)
checkbox
f.check_box :rotting <%= check_box_tag 'user_domains[]', k, @user_domains.has_key?(k), id: "domain-#{k}" %> Object : <div class="field"> <%= f.label "Categories" %><br /> <% for category in Category.all %> <%= check_box_tag 'user[category_ids][]', category.id, @user.category_ids.include?(category.id), :id => dom_id(category) %> <%= label_tag dom_id(category), category.name, :class => "check_box_label" %> <% end %> </div> Hash : dom_id 無法用, 它只吃 object <% UserDomain.domain.each do |k, v| %> <div> <%= check_box_tag 'user_domains[]', k, @user_domains.has_key?(k), id: "domain-#{k}" %> <%= label_tag "domain-#{k}", t("domain.#{k}") %> </div> <% end %>
file
<%= form_for @person do |f| %> <%= f.file_field :picture %> <% end %>
label + text_field
<%= f.label :nickname %> <%= f.text_field :nickname %> # 讓 text input disable disabled: true # 重新給值或 format datetime value: @case.deadline.strftime("%Y-%m-%d")
text_area
f.text_area :bio
button
<%= button_tag(type: 'submit', class: "btn btn-primary") do %> <i class="icon-ok icon-white"></i> Save <% end %>
input
f.submit "Submit", :disable_with => 'Submiting...' submit_tag "Submit", id: "foo-submit", data: { disable_with: "Please wait..." }
form
<%= form_for @user, url: user_path(@user), html: { method: :put, id: 'edit-user' } do |f| %>
取值
@user.email 或 f.object.email
link_to
<%= link_to tweet.zombie.name, zombie_path(tweet.zombie) %> <%= link_to tweet.zombie.name, tweet.zombie %>
二種寫法相同
label
f.label :name
password
f.password_field :password
number_field
f.number_field :price
range_field
f.range_field :quantity
email_field
f.email_field :email
url_field
f.url_field :website
telephone_field
f.telephone_field :mobile
筆記參考來源:http://blog.jex.tw/