2016年12月27日 星期二

C# MVC Pass multiple list from models & view & controller

參考來源:http://stackoverflow.com/questions/36892770/pass-multiple-list-from-multiple-models-to-view-from-controller

Models內容
public class MyViewModel {
   public List<table1> TheFirstTable {get;set;}
   public List<table2> TheSecondTable {get;set;}
}

Controller內容
MyViewModel viewModel = new MyViewModel();
viewModel.TheFirstTable = //first table content
viewModel.TheSecondTable = //second table content
return View(viewmodel);

View內容
//多筆資料
@foreach(var row in Model.TheFirstTable) {
    //do something with the row
}

//單筆資料
@Model.TheSecondTable

這樣就能同時輸出多筆不同的 List 嘍!

2016年11月17日 星期四

C# MVC how to create a project / controller / model / view (visual studio 2013)




C# MVC add Jquery libraries

Single page:

_layout.cshtml
@RenderSection("JavaScript", required: false)

view page
@section JavaScript
{
   <script type="text/javascript" src="@Url.Content("~/Scripts/SomeScript.js")"></script>
   <script type="text/javascript" src="@Url.Content("~/Scripts/AnotherScript.js")"></script>
}



2016年10月31日 星期一

Cloud9-RoR-jquery-validation-rails

參考來源(安裝):https://github.com/meowsus/jquery-validation-rails
參考來源(使用方式):http://tudip.blogspot.tw/2013/05/jquery-validate-in-rails-applications-by-tudip-technologies.html
doc說明:https://jqueryvalidation.org/validate/

因為我是另外用$.get及jquery-ui的dialog套件相互配合來載入編輯頁面,所以js碼必需寫在被載入的頁面裡,不然其實可以直接寫在coffee檔裡的。

首先,安裝jquery-validation-rails,編輯Gemfile,加上
# validation
gem 'jquery-validation-rails'

執行指令
$ bundle

編輯app/assets/javascripts/application.js檔,加上
//= require jquery.validate
//= require jquery.validate.additional-methods

編輯app/assets/stylesheets/application.css檔,加上
.error {
  color: #FF0000;
}

veiw檔及js的部份,需要套入驗證的text_field記得加上:class => "required",js的debug如果打開來的話,表單就算全部驗證通過也不會被送出哦!如果已測試完成,記得要把那行註解掉。
<%= form_for @rcalendar, :url => rcalendars_path do |f| %>
  <%= f.hidden_field :v_calendar_id, :value => params[:vid] %>
  <div>
  <%= f.label :fb_nickname, "Facebook姓名" %><span style="color:#FF0000">(必填)</span>
  <%= f.text_field :fb_nickname, :class => "required" %>
  </div>
  <div>
  <%= f.label :fb_urls, "Facebook網址" %><span style="color:#FF0000">(必填)</span>
  <%= f.text_field :fb_urls, size: "57", :class => "required" %>
  </div>
  <div>
  <%= f.label :content, "內容" %>
  <%= f.text_area :content, size: "50x10"  %>
  </div>
  <div>
  <%= f.label :password, "取消預約密碼" %><span style="color:#FF0000">(必填)</span>
  <%= f.password_field :password, :class => "required", autocomplete: "off" %>
  </div> 
  <div>
  <%= f.label :password_confirmation, "確認取消密碼" %><span style="color:#FF0000">(必填)</span>
  <%= f.password_field :password_confirmation, :class => "required", autocomplete: "off" %>
  </div>      
  <%= f.submit "確定" %>
<% end %>

<script type="text/javascript">
$('#new_rcalendar').validate({
  //debug: true,
  rules: {
    'rcalendar[fb_nickname]': {
      required: true
    },
    'rcalendar[fb_urls]': {
      required: true,
      url: true
    },
    'rcalendar[password]': {
      required: true,
      minlength: 5
    },
    'rcalendar[password_confirmation]': {
      required: true,
      minlength: 5,
      equalTo: "#rcalendar_password"
    }
  },
  messages: {
    'rcalendar[fb_nickname]': {
      required: '必須填寫'
    },
    'rcalendar[fb_urls]': {
      required: '必須填寫',
      url: '請輸入有效的網址'
    },
    'rcalendar[password]': {
      required: '必須填寫',
      minlength: '長度不得小於5位數'
    },
    'rcalendar[password_confirmation]': {
      required: '必須填寫',
      minlength: '長度不得小於5位數',
      equalTo: '密碼不符'
    }
  }
});
</script>

測試時欄位如果一開始就為空,保持在空值狀態時是不會秀出錯誤的,除非輸入資料後再清空才會有錯誤的提醒,就這點比較讓我匪夷所思,在此提醒一下大家,免得像我一樣一直鬼打牆。

2016年10月25日 星期二

Google Domains 申請

先提供網域的價格表給大家參考。

  1. 使用VPN跳板,選擇U.S.連線,不然會被擋下。
  2. 然後到https://domains.google/輸入(查詢)你要的domains。
    (Search for a domain name...處輸入)
  3. 查詢後會列出可供購買的網域列表,選擇你想要購買的網域。
    Google官方教學:https://support.google.com/domains/answer/4491208
  4. 填寫個人資料可以參考這篇文章步驟7。
    很重要!很重要!很重要!地址的部份請參考此篇文章的回覆才能順利送出表單哦!
  5. 付費時沒有Google Wallet 電子錢包也沒關係,地區記得選U.S.就好,然後輸入自己的卡號。
  6. 接著會問你要把網域直接套用到website或是將相關資訊寄到email裡,擇其一。
這樣就算全部完成嘍!希望大家都能順利申請,之後應該會寫一篇怎麼使用的文章唄!

Cloud9-RoR-fullcalendar-rails & CRUD Part.1

*2016/11/1-更新calendar.coffee、calendar.controller,將_form.html.erb改回new.html.erb。

參考來源(jquery-ui):https://rubygems.org/gems/fullcalendar-rails/versions
參考來源(CRUD):http://vinsol.com/fullcalendar-demo

C:會套用前幾篇中提到的one-to-many頁面。
R:使用jquery-ui的套件,將事件的detail顯示在dialog裡。
U:本篇不做。
D:依附在read底下,點選某一日曆上的事件時才會載入delete按鈕,如該事件已有人回復/預訂,則不可刪除。

首先安裝 jquery-ui-rails
打開Gemfile檔,加入
# jquery-ui
gem 'jquery-ui-rails'

編輯application.js,加入
//= require jquery-ui

編輯application.css,加入
*= require jquery-ui

執行指令
$ bundle install


CRUP實做
編輯calendars_controller.rb
  before_action :set_calendar, :only => [ :destroy]
  def index
    @calendars = Calendar.
    select("calendars.id", "IF(calendars.user_id = '#{current_user.id}', 1, 0) AS isedit",
    "IF(rcalendars.fb_nickname IS NULL, 1, 0) AS reserved",
    "CONCAT(calendars.vdate , ' ', calendars.vtime, ':00:00') AS dt", 
    "CONCAT(users.username, ' ', IFNULL(rcalendars.fb_nickname, '')) AS title",
    "CONCAT(calendars.vdate , ' ', calendars.vtime, '點<br/>', IFNULL(rcalendars.content, '')) AS description").
    joins("LEFT JOIN users ON users.id = calendars.user_id LEFT JOIN rcalendars ON rcalendars.calendar_id = calendars.id")
    #if json file(index.json.jbuilder) like to link use json.url calendar_path(calendar)
  end

  def new
    @calendar = []
    15.times do
      @calendar << Calendar.new
    end
    render :layout => false
  end
  
  def create
    if params.has_key?("calendar")
      @calendar = Calendar.create(calendar_params(params["calendar"]))
    else
      params["calendars"].each do |calendar|
        if calendar["issave"] && calendar["vdate"] != ""
          @calendar = Calendar.create(calendar_params(calendar))
        end
      end
    end
    
    #json
    respond_to do |format|
      if @calendar.save
        format.html { redirect_to calendars_url, notice: 'calendar was successfully created.' }
        format.json { render action: 'index', status: :created, location: @calendar }
      else
        format.html { render action: 'new' }
        format.json { render json: @calendar.errors, status: :unprocessable_entity }
      end
    end 
    #json
  end  

  def destroy
    @calendar.destroy
    redirect_to calendars_url
    flash[:alert] = "calendar was successfully deleted"
  end
  
  private
    # Use callbacks to share common setup or constraints between actions.
    def set_calendar
      @calendar = Calendar.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def calendar_params(my_params)
      my_params.permit(:user_id, :vdate, :vtime)
    end  

編輯calendar.coffee
$(document).ready ->
  # page is now ready, initialize the calendar...
  $('#new_event').click (event) ->
    $.get '/calendars/new', (data) ->
      #初始將a.html include div#iframe
      $('#create_event').html data
      return
    $('#create_event_dialog').dialog
      title: '新增'
      modal: true
      width: 500
      close: (event, ui) ->
        $('#create_event_dialog').dialog 'destroy'
        return
    return
    
  $('#create_event_dialog, #desc_dialog').on 'submit', '#event_form', (event) ->
    $spinner = $('.spinner')
  
    show_spinner = ->
      $spinner.show()
      return
  
    hide_spinner = ->
      $spinner.hide()
      return
  
    handle_error = (xhr) ->
      alert xhr.responseText
      return
  
    event.preventDefault()
    $.ajax
      type: 'POST'
      data: $(this).serialize()
      url: $(this).attr('action')
      beforeSend: show_spinner
      complete: hide_spinner
      success: refetch_events_and_close_dialog
      error: handle_error
    return
    
  $('#calendar').fullCalendar
    header:
      left: 'prev,next today'
      center: 'title'
      right: 'month'
    defaultView: 'month'
    loading: (bool) ->
      if bool
        $('#loading').show()
      else
        $('#loading').hide()
      return
    events: '/calendars.json'
    timeFormat: 'Ahh點'
    eventClick: (event, jsEvent, view) ->
      showEventDetails event
      return  
  return

showEventDetails = (event) ->
  $('#event_desc').html event.description
  title = event.title
  if event.isedit and event.reserved
    $('#delete_event').html '<form class="button_to" method="post" action="/calendars/' + event.id + '"><input type="hidden" name="_method" value="delete" /><input type="hidden" name="authenticity_token" value="' + $('meta[name="csrf-token"]').attr('content') + '" /><input data-confirm="Are you sure?" type="submit" value="Delete" /></form>'
  else
    $('#delete_event').html ''
  $('#desc_dialog').dialog
    title: title
    modal: true
    width: 500
    close: (event, ui) ->
      $('#desc_dialog').dialog 'destroy'
      return
  return

refetch_events_and_close_dialog = ->
  $('#calendar').fullCalendar 'refetchEvents'
  $('.dialog:visible').dialog 'destroy'
  return

編輯calendars.scss
.fc-h-event {
    cursor: pointer;
}

編輯calendars/index.html.erb
<div><%=link_to '新增', new_calendar_path, :id => 'new_event' %></div>

<div id="calendar"></div>

<!--隱藏表單 //-->
<div id = "desc_dialog" class="dialog" style ="display:none;">
  <div id = "event_desc">
  </div>
  <br/>
  <br/>
  <div id = "event_actions">
    <span id = "edit_event"></span>
    <span id = "delete_event"></span>
  </div>
</div>
<div id = "create_event_dialog" class="dialog" style ="display:none;">
  <div id = "create_event">
  </div>
</div>

新增的畫面

點開日曆事件時的畫面
可編輯自己的部份:

不可編輯他人的資料:

後台總算告個段落,只剩下套版了。

Cloud9-RoR-fullcalendar-rails & json

範例下載:https://github.com/FerPerales/fullcalendar_and_rails_example

請下載範例檔,使用現成的檔案就行嘍!(CRUD不使用本範例的套件)

套用json至fullcalendar
Copy app\views\events 下的index.json.jbuilder至cloud9中,@events及event的部份請更改成自己的model名稱哦!
json.array!(@calendars) do |calendar|
  json.extract! calendar, :id, :title
  json.start calendar.dt
end

編輯calendar_controller.rb,萬一欄位跟範例的不一樣該怎麼辦呢?我就剛好遇到這個問題,請參考index select()裡的寫法,joins不需要的人就拿掉吧!
  def index
    @calendars = calendar.select("calendars.id, CONCAT(calendars.vdate , ' ', calendars.vtime, ':00:00') AS dt , users.username AS title").joins(:user)
  end

編輯app\assets\javascripts底下的calendar.coffee
$(document).ready ->
  $('#calendar').fullCalendar
    header:
      left: 'prev,next today'
      center: 'title'
      right: 'month'
    defaultView: 'month'
    slotMinutes: 15
    loading: (bool) ->
      if bool
        $('#loading').show()
      else
        $('#loading').hide()
      return
    events: '/calendars.json'
    timeFormat: 'Ahh點'
  return

完成後的內容會像下圖



下一篇會教怎麼加入CRD,U的部份我不需要,加上沒時間,就跳過不做了。

2016年10月17日 星期一

Cloud9-RoR-one-to-many & create multiple records at once

參考文章:http://vicfriedman.github.io/blog/2015/07/18/create-multiple-objects-from-single-form-in-rails/
rails儲存的方法區別:http://rubyer.me/blog/262/

這次的功能需求是一次能夠存取多筆資料,且剛好是符合一對多的資料型態,先從一對多(user-to-calendars)的設定開始吧!

One-to-Many
User(one),編輯 app/models 底下的 user.rb 檔,加入
  has_many :calendars, :dependent => :delete_all

Calendars(many),一樣編輯 models 下的 calendar.rb,加入
  belongs_to :user

可以注意到 has_many 字尾有{s}(複數), belongs_to 是沒有的(單數)。


Create Multiple Records at Once
編輯calendar_controller.rb
  def new
    @calendar = []
    20.times do
      @calendar << calendar.new
    end
  end

  def create
    if params.has_key?("calendar")
      @calendar = calendar.create(calendar_params(params["calendar"]))
    else
      params["calendars"].each do |calendar|
        if calendar["issave"] && calendar["vdate"] != ""
          @calendar = calendar.create(calendar_params(calendar))
        end
      end
    end

    if @calendar.save
      redirect_to calendars_url
    else
      render :action => :new
    end
    flash[:notice] = "calendar was successfully created"
  end

編輯views/calendars/new.html.erb
<%= form_tag calendars_path do %>
  <% i=0 %>
  <table border="0">
    <tr>
      <td>儲存</td>
      <td>日期</td>
      <td>時間</td>
    </tr>
  <% @calendar.each do |calendar| %>
    <%= fields_for 'calendars[]', calendar do |f| %>
      <tr>
        <td>
        <div>
        <% if i < 1 %>
        <%= hidden_field_tag('calendars[][issave]', true) %>
        <% else %>
        <%= check_box_tag('calendars[][issave]', true) %>
        <% end %>
        <%= f.hidden_field :user_id, :value => current_user.id %>
        </div>
        </td>
        <td>
        <div>
        <%= f.date_field :vdate %>
        </div>
        </td>
        <td>
        <div>
        <%= f.select(:vtime) do %>
          <% (0..23).each do |t| -%>
            <%= content_tag(:option, t.to_s.rjust(2, '0'), value: t) %>
          <% end %>
        <% end %>
        </div>
        </td>
      <% i=i+1 %>
    <% end %>
    </tr>
  <% end %>
  </table>
  <div class="actions">
    <%= submit_tag %>
  </div>
<% end %>

執行後的畫面

完成後在日曆上看不到資料是正常的哦!因為我們還沒將資料套用到日曆上,下一篇就會介紹如何使用json將資料顯示在fullcalendar上哩!

2016年10月16日 星期日

CoffeeScript

記錄一下CoffeeScript的資源。

撰寫coffeescript時,縮排非常重要,它是靠縮排來判斷程式碼間的層級關係。

官網:http://coffeescript.org/
  • TABLE OF CONTENTS:範例 
  • TRY COFFEESCRIPT:CoffeeScript→Javascript
  • ANNOTATED SOURCE:源始碼

Javascript→CoffeeScript:http://js2.coffee/
將Javascript轉為CoffeeScript的寫法,對於初學者來說很有幫助。

2016年10月10日 星期一

Cloud9-RoR-fullcalendar-rails 安裝

參考來源:https://rubygems.org/gems/fullcalendar-rails/versions
參考文章/下載來源:https://github.com/bokmann/fullcalendar-rails
官網:https://fullcalendar.io/
doc說明:https://fullcalendar.io/docs/
範例參考(1):http://vinsol.com/fullcalendar-demo
範例參考(1)下載來源:https://github.com/vinsol/fullcalendar_rails
範例參考(2):http://blog.crowdint.com/2014/02/18/fancy-calendars-for-your-web-application-with-fullcalendar.html
輔助套件(必裝):https://github.com/derekprior/momentjs-rails

p.s.範例參考都有提供GitHub下載,可以用clould9另開一個新專案載入後試玩看看。

fullcalendar-rails需要用到momentjs-rails,所以我們先安裝monentjs-rails套件。如果想先檢查有沒有相關套件,可以執行以下指令:
$ gem list
底下會列出主機上所有安裝的gem套件,已經安裝的人可以跳過安裝步驟哦。

momentjs-rails
執行安裝指令
$ gem install momentjs-rails
$ bundle install

在Gemfile檔加上兩行
# momentjs
gem 'momentjs-rails'

編輯application.js檔,加入
//= require moment 

編輯test/test_helper.rb檔,加入
  test "truth" do
    assert_kind_of Module, Momentjs::Rails
  end

然後上傳下列的檔案到指定的資料夾中
  • lib:momentjs-rails.rb
  • vendor\assets\javascripts:moment.js、moment folder

fullcalendar-rails
執行安裝指令
$ gem install fullcalendar-rails
$ bundle install

在Gemfile檔加上兩行
# full calendar
gem 'fullcalendar-rails'

編輯application.css檔,加入
 *= require fullcalendar

編輯application.js檔,加入
//= require fullcalendar

如果想要轉換語系,再加入
//= require fullcalendar/lang/zh-tw

接下來有兩種套用方式,model跟view。

model:在app\assets\javascripts\找到該mode的.coffee檔,加入
$(document).ready ->
  $("#calendar").fullCalendar(
    lang: 'zh-tw' #轉換語系
    editable: true
    header:
      left: 'prev,next today'
      center: 'title'
      right: 'month,agendaWeek,agendaDay,listWeek'
    defaultView: 'month'
    height: 500
    slotMinutes: 15
  )

打開該model下的view(.html.erb)檔,再加入
<div id="calendar"></div>
就會顯示月曆了。

view:想套用單一頁面則打開該view(.html.erb)檔後,加入
<scrip>
$(document).ready(function(){
  $('#calendar').fullCalendar({
    lang: 'zh-tw', //轉換語系
    editable: true,
    header: {
      left: 'prev,next today',
      center: 'title',
      right: 'month,agendaWeek,agendaDay,listWeek'
    },
    defaultView: 'month',
    height: 500,
    slotMinutes: 15
  });
});
</scrip>

<div id="calendar"></div>

從這段起跟列印有關,不需要用到列印功能的人可以跳過。
----------------------------------------------------------------------------------
在stylesheets資料夾下新增一個application-print.css.scss檔。

編輯config/application.rb檔,加上
config.assets.precompile += ['application-print.css']

在需要列印的view頁面加入
<%= stylesheet_link_tag "application-print", :media => "print" %>
----------------------------------------------------------------------------------

上傳下列檔案
  • lib:fullcalendar-rails.rb及fullcalendar-rails folder
  • vendor\assets\javascripts:fullcalendar folder、fullcalendar.js
  • vendor\assets\stylesheets:fullcalendar.css、fullcalendar.print.css
希望大家都能順利的完成嘍!

2016年9月21日 星期三

PHP MVC laravel 學習過程記錄

因為最近接的案子業主對於PHP較有研究,於是決定重操舊業回頭學習PHP的MVC架構,不過為了讓環境單純化,所以這次是使用VMware Player來架設,這篇文章主要是來紀錄從架設到寫程式的過程,應該就只是單純的做剪剪貼貼,畢竟網路上已經有很多相關的教學文章,這篇只是把參考過的文章記錄下來而已。
  1. VMware Player:因為我的環境是Windows7 32-bit,但官網目前已經更新到64-bit,所以花了一段時間找檔案,如果你是64-bit的話,直接到官網下載最新版就行了。
    32-bit
    64-bit
  2. Windows 7 ISO檔:微軟有提供載點,只是要先輸入序號驗證。
  3. laravel-Windows:這個教學網是直接使用XAMPP的套裝軟體,能夠迅速的把PHP、MySQL及Apache安裝好。
    很重要!很重要!很重要!請下載PHP7的版本,PHP7在效能上提升很多,既然要用了當然要選最優的嘍!
  4. Sublime Text 3:這次選擇的編輯器,是說我也是第一次使用,請安裝Sublime Text 3的版本,完成後可以參考此篇(如果你是安裝laravel5,文章最下方安裝 Generators的部份請不要跟著做,該篇文章內所使用的Generators版本還不支援laravel5,想要使用該套件的話可以參考這篇來安裝Generators套件)裡面有介紹相關的laravel外掛。(請注意自己安裝的laravel版本,文章裡是4,但我是安裝5,所以在安裝時記得依據自己的版本來選擇)
  5. Laravel 5.3 預熱:介紹laravel5.3改變了哪些東西。
  6. 目錄及指令介紹laravel目錄及一些常用的指令,不過目錄介紹是針對舊版的laravel為主唷。
  7. php artisan指令:尚未實作,後續補上。
  8. Laravel官網:實作檔案的修改前先看看這篇吧!
  9. Laravel基本設定:安裝完laravel後需要更改的一些設定,不過此篇的寫法是屬於舊版本的寫法,檔案目錄的位置也不一樣了,修改記錄如下,我目前只做到routes的設定哦!
    文章路徑實際路徑修改內容
    app/config/app.phpconfig/app.php'timezone' => 'Asia/Taipei' 'debug' => env('APP_DEBUG', true),
    app/config/database.phpconfig/database.php 暫不修改
    app/routes.phproutes/web.phpRoute::get('/index.html', function() { return View::make('welcome'); });

2016年8月3日 星期三

Cloud9-RoR-link_to

參考來源:http://stackoverflow.com/questions/2124862/link-to-send-parameters-along-with-the-url-and-grab-them-on-target-page
詳細文章:http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to
參考文章:http://apidock.com/rails/v3.2.8/ActionView/Helpers/UrlHelper/link_to

link_to需要傳值時的寫法
<%= link_to "連結", products_path(:param1 => "value1", :param2 => "value2"), class: "color1" %>

link_to連結文字內容較複雜時的寫法
<%= link_to(product) do %>
  <img src="images/<%= product.image_url %>" class="img-responsive" alt=""/>
  <h3><%= product.title %></h3>
  <h4>$<%= product.price %></h4>
<% end %>

此篇將會不定期的更新哦!

2016年7月29日 星期五

Cloud9-RoR-Authentication:devise validate custom fields and rails-i18n

參考文章:https://ihower.tw/rails4/i18n.html
詳細介紹-validate:http://guides.rubyonrails.org/active_record_validations.html
詳細介紹-自訂警語:http://guides.rubyonrails.org/i18n.html#translations-for-active-record-models
參考來源:http://stackoverflow.com/questions/808547/fully-custom-validation-error-message-with-rails
參考文章:http://ricostacruz.com/cheatsheets/rails-i18n.html
下載 rails-i18n:https://github.com/svenfuchs/rails-i18n 

上一篇是介紹如何新增自訂欄位,這一篇就來教大家怎麼增加自訂欄位的驗證,雖然只有短短幾行,卻花費了我好多時間…總之,在打算放棄devise時,讓我找到了解答,還好最後還是守住了,神啊~讓我之後順利點吧!

打開app/models/user.rb檔,加入我們想要驗證的欄位名稱
  validates :cname, presence: true
  validates :phone1, numericality: true, length: { in: 9..12 }
  validates :zipcode, numericality: { only_integer: true }, length: { in: 3..5 }
  validates :address, presence: true

編輯Gemfile,加上
# 語系檔
gem "rails-i18n"

執行指令
$ gem install rails-i18n

在config/locales/下新增一個zh-TW.yml的檔案,用來指定各欄位顯示的文字,models用來指定rails/locale/底下的%{resource}名稱。
zh-TW:
  activerecord:
    models:
      user: "會員資料"
    attributes:
      user:
        cname: "姓名"
        email: "信箱"
        phone1: "電話1"
        zipcode: "郵遞區號"
        address: "地址"
        password: "密碼"
        password_confirmation: "確認密碼"

編輯config/application.rb
    # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
    config.i18n.load_path += Dir[Rails.root.join('rails', 'locale', '*.{rb,yml}').to_s]
    config.i18n.default_locale = "zh-TW"

    #devise_error
    config.action_view.field_error_proc = Proc.new { |html_tag, instance| 
      "<font style=\"color: #CC0000;\">#{html_tag}</font>".html_safe
    }

因為我發現 install 後檔案還是沒出現,可能要自行放上吧,如果你也是,就把下載 rails-i18n的檔案放到專案中,不過…我並沒有全放就是了,我放上的檔案如下:
  • bin/i18n-tasks, rspec
  • config/i18n-tasks.yml
  • lib (all)
  • rails (all)
  • space (all)
  • rails-i18n.gemspec
  • locales.thor
編輯 rails/locale/zh-TW.yml,把%{model}的部份取代為%{resource},並加上下列程式碼(綠色部份)
  errors:
    format: "%{attribute} %{message}"
      messages:
        not_saved:
          one: 有 1 個錯誤發生使得「%{resource}」無法被儲存。
          other: 有 %{count} 個錯誤發生使得「%{resource}」無法被儲存。

執行程式,連結到註冊頁面,按下SIGN UP鈕就可以看到下圖的警告視窗。











欄位文字的部份則會變成粗體紅字。









希望大家也能順利完成,本篇就到此結束,終於…寫了好幾個星期…

2016年7月12日 星期二

Cloud9-RoR-Authentication:devise add fields

參考文章:http://jacopretorius.net/2014/03/adding-custom-fields-to-your-devise-user-model-in-rails-4.html

如果想要在devise套件裡增加欄位該怎麼做呢?create the migrationd可以看此篇有關users的部份,以下就直接跳到create controller的步驟嘍!

首先,先新增一個RegistrationsController
$ rails g controller registrations

打開registrations_controller.rb檔,編輯內容,注意class的地方不一樣,有做繼承devise的動作
#class RegistrationsController < ApplicationController
class RegistrationsController < Devise::RegistrationsController  
  private

  def sign_up_params
    params.require(:user).permit(:cname, :phone1, :phone2, :address, :zipcode, :email, :password, :password_confirmation)
  end

  def account_update_params
    params.require(:user).permit(:cname, :phone1, :phone2, :address, :zipcode, :email, :password, :password_confirmation, :current_password)
  end
end

修改config/routes.rb
  #devise_for :users
  devise_for :users, :controllers => { registrations: 'registrations' }

Done.

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

這篇應該會更新一輩子。