经过大半天的折腾,终于可以让RoR在OS X系统里访问Sql Server数据库了。这里记录一下操作的过程,免得以后忘了。
从FreeTDS的官网上下载最新的稳定版的压缩包,然后,遵照这里的说明进行手工编译(好怀念微软的Setup.exe和*.msi啊),其中只需要前7步:
1. Download the latest stable release of freetds.
2. Extract freetds tgz file within Downloads
3. Open terminal and cd to Downloads/freetds-0.** folder
4. run “./configure”
5. run “cp /usr/bin/glibtool libtool” <----Important!
6. run "sudo make"
7. run "sudo make install"
这样,我们的FreeTDS就算是装好了。
就在命令行里执行: gem install tiny_tds
不要问我gem从哪里来的,google一下gem就会找到很多信息。在OS X里,gem是内置的。呵呵。
注意,如果没有安装FreeTDS的话,tiny_tds也肯定会安装失败,因为它依赖FreeTDS
同样,只需要在命令行里执行: gem install activerecord_sqlserver_adapter
gem 'tiny_tds'
gem 'activerecord_sqlserver_adapter'
在命令行里运行 bundle install,运行完毕之后会输出很多Using语句,看看tiny_tds和activerecord_sqlserver_adapter是否包含在里面,应该都包含在里面才正确。
打来RoR项目根目录下、config子目录下的database.yml文件,根据需要修改配置,比如:
development:
adapter: sqlserver
mode: dblib
dataserver: 10.4.30.77\Sql2005 # Name from freetds.conf, host or instance 'localhost\SQLEXPRESS'
host: 10.4.30.77 # Used if dataserver is blank.
port: 1433 # Used if host present. Default is 1433.
database: ALO_DB
username: db_user
password: xxxx
timeout: 5000
azure: false # for windows azure
可以创建model了: rails generate model MyShipper ShipperID:int ShipperName:string
对于时间紧、任务重的遇到同个问题的程序员兄弟,请直接看代码,跳过下面的絮叨文字。
最近都快成了一个JavaScript前台程序员了。。。原本我想只关注后台来着……没办法,工作需要啊~
今天一个同事突然跑过来,问我jQuery UI 里的DatePicker能不能增加一个Clear按钮,来个一键清除,我想强大的DatePicker肯定已经考虑到了这个需求,或许就是一个简单属性设置的事儿,结果,让我失望了,DatePicker并没有提供Clear功能,Google了一顿,结论是,或许曾经有,但从某个时间开始,基于某种原因被去掉了,并且再也没有回来过。网上有些人给了一些重度hack的做法,深入到控件的生成HTML的函数之中增加了一个Clear按钮。这对于我辈JavaScript菜鸟,实在是不敢妄动,哪怕只是Copy & Paste. 其实DatePicker提供了2个按钮, Today 和 Done,为何我们不从这个Done按钮入手,让它洗心革面,改造成一个Clear按钮,同时又尽量只从控件的外围打补丁呢?经过对DatePicker生成的HTML的分析,发现似乎并不能难。只需要用以下代码解决之。
1 $(document).ready(function ()
2 {
3 //用来存放当前正在操作的日期文本框的引用。
4 var datepicker_CurrentInput;
5
6 // 设置DatePicker 的默认设置
7 $.datepicker.setDefaults({ showButtonPanel: true, closeText: 'Clear', beforeShow: function (input, inst) { datepicker_CurrentInput = input; } });
8
9 // 绑定“Done”按钮的click事件,触发的时候,清空文本框的值
10 $(".ui-datepicker-close").live("click", function ()
11 {
12 datepicker_CurrentInput.value = "";
13 });
14 });
在最近做的一个项目中,使用jQuery Validation验证日期,遇到的问题和一个没有预料到的情况是,在ASP.NET MVC 3的项目中,对于 <input type="date" data-val="true" />的元素,如果调用form的valid方法验证form,虽然我没有添加日期验证的设置,仅仅type="date",但其依然调用了日期验证逻辑来验证日期格式是否正确。这本来是个不错的行为,但问题在于,其支持的日期格式有限,阅读jQuery Validation的代码会知道(当然,文档中也有说明),对于“date”,日期验证只是利用Javascript内置的处理来验证,反映到代码里,就是看new Date(日期字符串)能否成功。在我的电脑中,输入日期"9/5/2012"可以验证通过,但“2012-9-5”验证失败,后者显然也是一种正确的格式。我需要改变或者改善这种行为。如何做?
当然,我们可以修改jQuery Validation的源代码,但是首先,我引用的是CDN上的代码,其次,作为一个public的库,我想还是尽量不要自己去改动,日久天长,可能我们已经忘记了对它的修改,而官方更新新版本时,我们弄下来更新,结果就把我们自己的修改给覆盖了。更好的办法,是打补丁,从外部把date的验证函数替换成我们自己的。这里或许要感谢Javascript的OO还不是那么彻底,并没有把那些内置验证方法整成protected/private,看了源代码之后,替换的方法很简单,在引用jQuery Validation的源码之后,再这样替换:
$.validator.methods.date = function (value, element)
{
// Date.parse函数源自另外一个处理日期的库
return this.optional(element) || Date.parse(value) != null;
};
此外替换默认的message,也可以用同样的办法,比如:
$.validator.messages.date = "hey, you entered an invalid date"
当然,处理messages有其他支持的更好的办法,这在jQuery Validation的全球化和本地化的说明中有提及。
原文和演示在这里:http://jsfiddle.net/DkHyd/
我在这里直接粘贴出代码作为备份:
首先是演示用的Html,这里我简化一点内容,使其更短一些
Html Code
<h1>Toggle Panels</h1>
<div id="notaccordion">
<h3><a href="#">Section 1</a></h3>
<div>
<p>
Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer
</p>
</div>
<h3><a href="#">Section 2</a></h3>
<div>
<p>
Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet
</p>
</div>
<h3><a href="#">Section 3</a></h3>
<div>
<p>
Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis.
</p>
<ul>
<li>List item one</li>
<li>List item two</li>
<li>List item three</li>
</ul>
</div>
<h3><a href="#">Section 4</a></h3>
<div>
<p>
Cras dictum. Pellentesque habitant morbi tristique senectus et netus
</p>
<p>
Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus.
</p>
</div>
</div>
然后是关键,jQuery代码:
1 $.fn.togglepanels = function(){
2 return this.each(function(){
3 $(this).addClass("ui-accordion ui-accordion-icons ui-widget ui-helper-reset")
4 .find("h3")
5 .addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-top ui-corner-bottom")
6 .hover(function() { $(this).toggleClass("ui-state-hover"); })
7 .prepend('<span class="ui-icon ui-icon-triangle-1-e"></span>')
8 .click(function() {
9 $(this)
10 .toggleClass("ui-accordion-header-active ui-state-active ui-state-default ui-corner-bottom")
11 .find("> .ui-icon").toggleClass("ui-icon-triangle-1-e ui-icon-triangle-1-s").end()
12 .next().slideToggle();
13 return false;
14 })
15 .next()
16 .addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom")
17 .hide();
18 });
19 };
20
21 $("#notaccordion").togglepanels();
jQuery Mobile 在我开发移动web站点的时候,帮了很大的忙,但是今天发现一个问题,就是在执行listview("refresh")函数之后,开了data-inset="true"的listview原来的圆角边框变成了直角边框了。。。经过调试发现,在调用refresh之后,listview中的第一个 li 的 class 缺少了 ui-corner-top,而最后一个 li 缺少了 ui-corner-bottom,解决的办法很简单,就是refresh之后把这2个class 加上。
1 // lv就是listview对象
2 lv.listview("refresh");
3 lv.find("li:first").addClass("ui-corner-top");
4 lv.find("li:last").addClass("ui-corner-bottom");
这或许应该算是一个bug吧~