2016年6月29日 星期三

Cloud9-RoR-Migration(bin/rake db:migrate)

參考文章:https://ihower.tw/rails4/migrations.html

為什麼現在才要寫這篇呢?因為發現還是要專門對它做點紀錄,好方便以後喚醒自己的記憶。

Migration,用來控制資料庫結構的檔案。migration的好處就是會自動偵測哪些檔案已經執行過哪些還沒,在團隊合作開發時超級方便的,不需要擔心資料庫結構不同步的問題。

-----------------以下資料出處請詳見參考文章-----------------

資料表修改:
  • create_table(name, options) 新增資料表
  • drop_table(name) 移除資料表
  • rename_table(old_name, new_name) 修改資料表名稱
  • change_table 修改資料表欄位

欄位修改:
  • add_column(table, column, type, options) 新增一個欄位
  • rename_column(table, old_column_name, new_column_name) 修改欄位名稱
  • change_column(table, column, type, options) 修改欄位的型態(type)
  • remove_column(table , column) 移除欄位

索引(key值):
  • add_index(table, columns, options) 新增索引
  • remove_index(table, index) 移除索引
※options 可為空,或是:unique => true表示這是唯一。


外來鍵修改:
  • add_foreign_key(from_table, to_table, options)
  • remove_foreign_key(from_table, to_table, options)
※options 可為空,或是可自定:column => from_table_foreign_key_column (預設是{to_table}_id)和:primary_key => to_table_primary_key_column(預設是id)。

-----------------以上資料出處請詳見參考文章-----------------

這邊就只是單純紀錄這次要修改專案的部份,想要有更進一步了解關於migration用法的人,可以到參考文章有提供很多範例哦。

先新增一個migration檔,檔案的位置會在db/migrate底下,我要在users及products底下新增欄位
$ rails g migration add_fields_to_users_products

打開「日期&時間&_add_fields_to_users_products.rb」檔
class AddFieldsToUsersProducts < ActiveRecord::Migration
  def change
    add_column :users, :cname, :string
    add_column :users, :phone1, :string
    add_column :users, :phone2, :string
    add_column :users, :address, :string
    add_column :users, :zipcode, :string
    
    add_column :products, :startdate, :datetime
    add_column :products, :enddate, :datetime
    add_column :products, :stock, :integer
    add_column :products, :disstartdate, :datetime
    add_column :products, :disenddate, :datetime
    add_column :products, :disprice, :integer
    add_column :products, :discontext, :text
    add_column :products, :predictdate, :datetime
  end
end

create一個model(同時也會create一個migration檔)
$ rails g model style product_id:integer title:string image_url:string

系統會自動建置以下的檔案
      create    db/migrate/20160629071919_create_styles.rb
      create    app/models/style.rb
      invoke    test_unit
      create      test/models/style_test.rb
      create      test/fixtures/styles.yml

執行指令
$ bin/rake db:migrate

資料結構修改完成!

2016年5月31日 星期二

C# MVC Validation Summary on Multiple Forms

參考文章:http://stackoverflow.com/questions/5342427/specify-validation-summary-on-multiple-forms

在同一個頁面裡有多個form時,怎麼指定驗證的訊息要顯示在哪個form裡?
@using (Html.BeginForm("update1", "form1"))
{
  if (Request.Form.AllKeys.Contains("btn1"))
  {
    @Html.ValidationSummary()
  }
                
  @Html.LabelFor(m => m.PointA1)
  @Html.TextBoxFor(m => m.PointA1)

  @Html.LabelFor(m => m.PointB1)
  @Html.TextBoxFor(m => m.PointB1)
                    
  <br />
  <input type="submit" name="btn1" value="確定" /> 
}

@using (Html.BeginForm("update2", "form2"))
{
  if (Request.Form.AllKeys.Contains("btn2"))
  {
    @Html.ValidationSummary()
  }
                
  @Html.LabelFor(m => m.PointA2)
  @Html.TextBoxFor(m => m.PointA2)

  @Html.LabelFor(m => m.PointB2)
  @Html.TextBoxFor(m => m.PointB2)
                    
  <br />
  <input type="submit" name="btn2" value="確定" /> 
}
利用submit的name就好嘍!

2016年5月6日 星期五

C# MVC Read CSV 亂碼問題

csv:big5編碼
Web:utf8編碼

導致檔案讀取中文時會變亂碼,其實只要一個簡單的步驟就能解決了。
//原:
var dataList = new CsvReader(new StreamReader(path)).GetRecords<FunUpload>().ToList();
//修改後:
var dataList = new CsvReader(new StreamReader(path, Encoding.Default)).GetRecords<FunUpload>().ToList();

這樣就能正確讀到中文嘍!

2016年5月3日 星期二

Cloud9-RoR-Shopping Cart 購物車 Part.3

參考影片-第五篇:https://www.youtube.com/watch?v=HSMqi913SL4
本篇在教如何將商品加入購物車。(有些人可能會遇到加入購物車後的頁面有出錯的冏境,影片中沒有提到怎麼解決的,我是自己亂試出來的,可以參考看看)
參考影片-第六篇:https://www.youtube.com/watch?v=m7BiZ0dAXh8
加入頁面的讀取權限。

第五篇跟第六篇最後的結果直接寫一起嘍!因為會編輯同樣的檔案。

編輯views/products/index.html.erb,加入藍色那行。(第五篇)
...
        <td><%= link_to 'Edit', edit_product_path(product) %></td>
        <td><%= link_to 'Destroy', product, method: :delete, data: { confirm: 'Are you sure?' } %></td>
        <td><a href="/cart/<%= product.id %>">加入購物車</a></td>
      </tr>
    <% end %>
...

編輯views/cart/index.html.erb。(第五、六篇)
<h1>你的購物車</h1>

<% if @cart.empty? %>
  <p>購物車中沒有任何商品</p>
<% else %>
  <%= link_to '清空購物車', cart_clear_path %>
<% end %>

<br/><br/><br/>

<% total = 0 %>

<ul>
<% @cart.each do | id, quantity | %>
    <% product = Product.find_by_id(id) %>
    
    <li>
        <%= link_to product.title, product %>
        <p><%= product.description %></p>
        <p><%= number_to_currency(product.price, :unit => '$') %></p>
        <p>Quantity: <%= quantity %></p>
    </li>
    <% total += quantity * product.price %>
<% end %>
<p><strong><%= number_to_currency(total, :unit => '$') %></strong></p>
</ul>

編輯cart_controller.rb,加入權限讀取,限制一定要登入會員後才能讀取頁面,except是指除了[:index]外,其餘action都必須要限制登入才能讀取。(第六篇)
class CartController < ApplicationController  
  before_action :authenticate_user!, except: [:index]
  def add
    id = params[:id]  
  ...
end

編輯page_controller.rb,一樣加入權限讀取,跟上方不一樣的是except改成only,only即指只有在[:contact]裡的action才需要做限制。(第六篇)
class PageController < ApplicationController
  before_action :authenticate_user!, only: [:contact]
  
  def home
  end
  ...
end

如果頁面在加入購物車後會出錯,請先檢查routes.rb,是否有設定好。
  root 'page#home'
  
  devise_for :users
  
  get '/cart' => 'cart#index'
  get '/cart/clear' => 'cart#clearCart'
  get '/cart/:id' => 'cart#add'
  #get 'cart#index'

  resources :products

  get 'page/about'

  get 'page/faqs'

  get 'page/contact'
這是我routes.rb的內容,routes.rb裡的內容順序是有意義的哦,我將原本放在中間的root 'page#home'移到最前面後再存檔就能work了,很神奇唄!連我都不大清楚why…會不會是我一開始就沒存檔…

購物車的部份就到這邊全部結束。

2016年4月28日 星期四

Cloud9-RoR-Shopping Cart 購物車 Part.2

參考影片-第三篇:https://www.youtube.com/watch?v=Wo2-PcGD4mE
這篇都在教設計版面,個人覺得可看可不看。
參考影片-第四篇:https://youtu.be/WRVwfVUaj_Y?t=4m10s
購物車code的部份。(為什麼我會設定4分10秒開始播放呢?因為前面都在講唔欸某欸…)

第三篇都在說明版面的設計(html、css),第四篇是購物車的部份,所以決定把三、四篇寫在一起,才不會太空虛…

以下是第三篇的檔案內容,其他就不再多加贅述了哦!如果你心裡有其他想要的設計,那就不需要照著做,我是想照著他的步驟有了基本設計後再來做調整修改,對我來說比較順手。

views/layouts/application.hrml.erb
<!DOCTYPE html>
<html>
<head>
  <title>Workspace</title>
  <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
  <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
  <%= csrf_meta_tags %>
</head>
<body>
<nav id="nav">
  <div id="page_nav">
    <%= link_to('首頁', root_path) %>
    <%= link_to('產品', products_path) %>
    <%= link_to('關於我們', page_about_path) %>
    <%= link_to('問與答', page_faqs_path) %>
    <%= link_to('聯絡我們', page_contact_path) %>
  </div>
  
  <div id="sign_in">
    <% if user_signed_in? %>
      Signed in as <%= current_user.email %>. Not you?
      <%= link_to('登出', destroy_user_session_path, :method => :delete) %> |
      <%= link_to('修改密碼', edit_registration_path(:user)) %>
    <% else %>
      <%= link_to('註冊', new_registration_path(:user)) %> |
      <%= link_to('登入', new_session_path(:user)) %>
    <% end %>
  </div>
</nav>

<div id="main_wrap">
  <% if notice %>
    <p class="alert alert-success"><%= notice %></p>
  <% end %>
  <% if alert %>
    <p class="alert alert-danger"><%= alert %></p>
  <% end %>
  
  <%= yield %>
</div>
</body>
</html>

app/assets/stylesheets/application.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, vendor/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 styles
 * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
 * file per style scope.
 *
 *= require_tree .
 *= require_self
 */

*{
    margin: 0;
    padding: 0;
}

#nav{
    width: 100%;
    height:40px;
    background: #000;
    float: left;
}

#page_nav a, #sign_in a {
    line-height: 40px;
    color: #FFF;
    padding: 0 20px 0 20px;
    text-decoration: none;
}

#page_nav {
    margin:  0 0 0 5%;
    float:  left;
}

#sign_in{
    float: right;
    margin:  0 5% 0 0;
}

#main_wrap {
    width: 90%;
    float: left;
    margin: 20px 5% 0 5%;
    
}
----------------------------------------------------

第四篇,routes.rb購物車的address設定,編輯成下列內容
  get '/cart' => 'cart#index'
  get '/cart/clear' => 'cart#clearCart'
  get '/cart/:id' => 'cart#add'
*get '{網址}' => '{controller}#{action}'

文章有提到本來要把cart的controller檔案內容放到影片的說明,不過沒放,以下就是cart_controller.rb內容,拿去用唄!
class CartController < ApplicationController
  
  def add
    id = params[:id]
    #if the cart has already been created, use the existing cart else create a new cart
    if session[:cart] then
      cart = session[:cart]
    else
      session[:cart] = {}
      cart = session[:cart]
    end
    #if the product has already been added to the cart, increment the value else set the value to 1
    if cart[id] then
      cart[id] = cart[id] + 1
    else
      cart[id] = 1
    end
    redirect_to :action => :index
  end
  
  def clearCart
    session[:cart] = nil
    redirect_to :action => :index
  end
  
  def index
    #if there is a cart , pass it to the page for display else pass an empty value
    if session[:cart] then
      @cart = session[:cart]
    else
      @cart = {}
    end
  end
  
end

看完後是不是有空虛、寂寞、覺得冷的情形呢…

Cloud9-RoR-實用指令

因為我太愛忘記一些常用到的指令了,所以寫一篇幾乎每次撰寫code時都會用到的指令大全…

執行網站
$ rails s -b $IP -p $PORT

mysql重啟
$ mysql-ctl restart

建立一個controller檔
$ rails g controller controller_file_name

建立一個migration檔
$ rails g migration migration_file_name

建立/更新資料表結構
$ bin/rake db:migrate

查詢routes
$ rake routes

這篇應該會更新一輩子。

2016年4月27日 星期三

Cloud9-RoR-Shopping Cart 購物車 Part.1

參考影片-第一篇:https://www.youtube.com/watch?v=4jVOnrUvCQQ
主要是在介紹網站建置好的模樣,以及網站功能,可以先看看哦!
參考影片-第二篇:https://www.youtube.com/watch?v=4OPdxPawXrw
開始寫code嘍!不過如果你是用Cloud9,前面的一些步驟可以不用做,像是專案的建置等等,而且本影片的會員功能也是使用devise套件,可以到這裡看看,我有稍做介紹哦。(mail驗證的部份請先不要打開)

先寫寫第二篇的步驟吧!

如果你是開一個新專案,請先執行下面的步驟。
$ bundle install
$ mysql-ctl restart

Mysql database的設定檔請參考這裡

建立page controller及其view檔
$ rails g controller page home about faqs contact

打開routers.rb檔,把page#home指定為首頁
root 'page#home'
page 'page/home'   //記得刪掉哦

建立product的controller
$ rails g controller product title:string description:text image_url:string price:integer category:string subcategory:string

建立product資料表
$ bin/rake db:migrate

建立cart controller
$ rails g controller cart index

接著就是使用devise套件嘍,請參考這裡,當然也可以照著影片的步驟做,我就不再做重複的解說了。

在建立好devise之後,有個步驟會修改layouts/application.html.erb檔,這是我的application.html.erb最後的長相。
<!DOCTYPE html>
<html>
<head>
  <title>Workspace</title>
  <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
  <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
  <%= csrf_meta_tags %>
</head>
<body>
<% if user_signed_in? %>
    Signed in as <%= current_user.email %>. Not you?
    <%= link_to('登出', destroy_user_session_path, :method => :delete) %> |
    <%= link_to('修改密碼', edit_registration_path(:user)) %>
<% else %>
    <%= link_to('註冊', new_registration_path(:user)) %> |
    <%= link_to('登入', new_session_path(:user)) %>
<% end %>

<br/><br/>
<%= link_to('首頁', root_path) %>
<%= link_to('關於我們', page_about_path) %>
<%= link_to('問與答', page_faqs_path) %>
<%= link_to('聯絡我們', page_contact_path) %>
      
<% if notice %>
  <p class="alert alert-success"><%= notice %></p>
<% end %>
<% if alert %>
  <p class="alert alert-danger"><%= alert %></p>
<% end %>

<%= yield %>

</body>
</html>

第二篇影片也到此結束了。這篇像在寫回憶錄,我是做完整個步驟了才來補寫日誌,所以不確定是不是有遺漏的地方,我想應該是沒有。影片中沒有做到database的設定,如果你是要用mysql就一定要補做我上面提到的database設定檔,否則cloud9的預設db是sqlite哦!