Pass JavaScript variables to Rails controller 1
Google query doesn’t give much useful result on this topic. What we discuss here is if there is a value/function getParameters() in JavaScript returns "message = hello_world" (a URL query). How do you pass the JS variable into controller?
link_to_remote
Most common way is using link_to_remote which constructs an Ajax call, but the drawback is you have to handle the params[:message] using RJS template (or please let me know if I was wrong). Here is the example:
<%= link_to_remote "Create Post", :url => {:controller=>'posts', :action =>'new'}, :method => :post, :with =>"getParameters();" %>
As you see, the :with option will eventually become :with => "message=hello_world". A new parameter is accessible by calling params[:message]. But what if I only want to render another page?
capture block
Capture block captures a variable for the view which can be reused. The idea is to call the JavaScript inside capture block to pass it as a Rails variable in view. The @param variable is readable in the view.
<% @param = capture do %>
<%= javascript_tag "document.write(getParameter());" %>
<% end %>
link_to_function
Remember that we have already passed the JavaScript value to @param variable, it is used here. An inline redirect_to does the trick, that redirects to the new action and value is accessible by calling params[:message].
<%= link_to_function "Create Post" do |page|
page.redirect_to "/posts/new" + "?" + @param
end %>
I’m sure that you will have other ways of using these tricks in difference situation, but hope you get the idea and use them whenever is suitable.
Passing Rails restful_authentication in rspec
Plugins in Rails are useful shortcuts, they produce better implementations for some areas. I recently come across an issue of passing model controller authentication, but the before_filter :login_required stops me testing my code in Rspec. By using mock and stub technique can pass the authentication test.
All you have to do is inserting these code before your rspec test (or place it somewhere in helper class)
current_user = mock_model(User, :id => 1)
controller.stub!(:login_required).and_return(:true)
controller.stub!(:current_user).and_return(current_user)This tells the test that
:login_required always returns :true and the variable @current_user returns a mock model that is not nil.
Offline Rails Documentation
Although you can run gem server to have a rails rdoc running on localhost, the rdoc rails document could be troublesome to find a specific method you would like to know about. Fortunately, you may want to try out an ajax improved rails documentation:
- RailsBrain provides a free downloadable (free) offline documentation for rails. It has the lastest version 2.2.2 available for download. The ajax feature allows developer search method, class or file name via a input box. It’s a sufficient tool and I am using it now for development.
- Gotapi is an online API collections. you can manage/view/search all the API you are currently using in any languages(e.g. PHP, Java, .net and of course rails). Similar features are privided as RailsBrains, but it’s only available online.
Updates on March 24 2009
- Railsapi.com is a recent new project and is hosted on GitHub. It has better search capabilities. Intresting to note that it does not support Internet Explorer is currently (may be more specific version or not been IE tested). Apart from that, it’s smart, tidy and downloadable Rails doc.
"Fork Ruby" Summary (RubyConf 2008)
I like screencast and keynote, they are great ways of learning practically. But some people don’t have much time to watch or listen to all these. Or maybe you forgot some ideas were presented, but it’s difficult to select the part you want to find in the video – you end up with watching the video again sometimes. So here I typed in a short summary of the keynote. If you are still interested, it’s worth to watching the video. And thanks to David Thomas giving this talk.
Presenter: David Thomas
Background: Last RubyConf attended was in 2005, started working on Ruby back in 1999. He wrote books, talked at many events and went to a lot of conferences. HE recently went to many Rails conferences.
Why Fork Ruby
There are a lot of active project forking Ruby interpreter, e.g. JRuby, IronRuby, MacRuby, but they are not forking the Ruby language.
Problem with Release Time
1.0 -> 1.2 tookk 14 months -> 1.4 (8 months) -> 1.6 (13 months) -> 1.8 (48 months) -> 1.9 (54 months)
- As you can see, bigger changes we make, the bigger challenges they are, more time required for next release.
- The bigger changes make developer difficult to adopt to these new features.
- Less people use the new release feature, release team will not be able to find problems.
Some (Potential) Projects Ideas
RubyLite
RubyLite is a light version of Ruby. The idea is that moving those listed less used features into Gem, developer install those gems only when they needed.
- One of the things we can do with RubyLite is to lose some language features that we normally don’t use (e.g.):
- %q delimiters
- implicit string concatenation
- alias
- nested assignment
::sign for method call
- And other features we can get rid of: class variables, global variables, many combination of
$sign,unless/until,protected,proc - One encoding will make library much smaller, so how about support utf8.
- Losing Built-in classes and modules:
Complex,File::Stat,FileTest,Mutex,ObjectSpace,Process::Gid/Status/Sys/Uid,Rational,TreadGroup - Losing Built-in methods, a lot of methods are vibrations that produces the same result.
Parallel Ruby
Ruby already have the construction to produce parallelism: a, b = b, a
Ideally, Dave suggested that we could perform calculation using this parallel feature in separate threads or processes: a, b = calc1(x), calc2(y). He used some sample code of finding longest word in English, which demonstrated that a few lines code produced Map/Reduce.
Optionally-typed Ruby
Closure-based Ruby
This Is the Ruby with block, and it should be easy to create lambda. Suggestion is to remove
{} sign for hash. Maybe we can express methods and classes in blocks.Conclusion
There is nothing wrong with Ruby, “but that shouldn’t stop us from having fun”. The community should fork Ruby and experiment with it. If the result is positive, they will be put in main Ruby release. The Ruby release itself should not be part of the experiment.
RubyGem update on Leopard
I have a RubyGem version 1.2.0 installed on Leopard. If you would like to update RubyGems to a newer version, the RubyGem user guide suggests for modern versions( >0.8.5 ) can use the following command:
gem update —systemBut, console told me the 1.2.0 is the latest version – Nothing to update! The work around is to use install rubygem-update:
gem install rubygems-update
update_rubygemsCheck installed version:
MBP:~ Jay$ gem —version
1.3.1So now, I’m able to pull the latest rSpec plugin into my Rails project.
VirtualHost browser cache
Setting up a virtual host on PC, Mac or Linux isn’t difficult, but the browser cache problem drives me crazy. Apart from editing the /etc/hosts mappings and httpd.conf, you need to restart both Apache and browser. Refreshing the browser(Firefox) doesn’t clean the cache, so the result will be always add /xampp/index.php at the end of the virtual host name.
Leopard system environment PATH setting
Leopard PATH setting is quite different from Tiger. Configuring PATH on Tiger, we used to either modify the /etc/path or user path configuration. With Leopard, system-wide path configuration is managed by /etc/profile. The file loads a path_helper script. So what the script does?
The path_helper constructs the system environment PATH in this order:
- Reads the local user configuration first, under
~/.bash_login - Appends default system paths
/usr/bin:/bin:/usr/sbin:/sbin - Reads the paths line by line in
/etc/paths - Retrieves all the files in
/etc/paths.d/that contains other packages configurations. For example, I created a file/etc/paths.d/systemand stuff in some user paths settings. They are appended after step 3.
In my case, I wanted my XAMPP packages overrides the default Leopard MySQL, PHP and Apache paths ( so I don’t have to type in /Application/xampp/xamppfile/bin to use the command every time, also the package is easier to manage ). So just put the paths in the ~/.bash_login, that will override the system default.
Close the Terminal and open it again, to check your path settings, type:
echo $PATHThere we go, it’s updated.
Git:更好的SCM版本管理系统
一直在忙着工作的事情,清闲下来准备一下毕业项目的资料。特别是代码版本管理的软件,有考虑到CVS, SVN等等,这些大多数是中心服务器结构的管理,最近看到Google工程师开发的Git, 让我感到一阵兴奋。
Linus Torvalds 开发了Git,一开始主要因为CVS和SVN不能满足开源的需求,需要一种新的方式管理Linux Kernel。Git是一个distributed SCM. 他的最大优势在于开发人员可以随意的创建自己的Brunch,简便多版本的整合(merge)问题,并且优化下载速度。
如果有人用过CVS, SVN在一个开发小组,都会发现这样的问题:大家都不能Commit,直到觉得代码被第二个开发人员review过,或者通过测试才可以,这样才能保持Source trunk的整洁。这样是件很麻烦的事情,如果在SVN, CVS上创建branch, 做自己的一些新功能的试验,也会造成麻烦,你会想到底用什么tag? 大的公司里面会有一堆的规则创建branch(加B下划线版本号码等等),然后整合到trunk上又给自己代来一堆麻烦,所以如果用过centerailized SCM开发人员大都会在trunk上开发。
如果你是一个充分利用Brunch的开发人员,那Git可以是一个不错的选择。给个Git官方网站,还有YouTube 2005年的Git开发介绍会(一个小时的录像)。
CSS优化:减少HTTP Requests
大多数的前端用户都会遇到一个问题,那就是下载速度。对于网络优越的用户,不是问题,但是考虑到移动用户或者是网络条件较差的使用者,最终要的是速度。现在的网站有很多的内容,比如Flash, 图像,声音,JavaScript等等都会减慢页面下载速度。
最基本的优化方法是减少客户端对HTTP Requests。有很多方法可以实现:
使用单个文件。就是说尽量把多个文件的CSS,或者JavaScript放到一个文件里面。虽然有时后我们需要不同的样式在不同的界面,但是在开发过程中能尽量考虑到这个问题,会给减少页面反馈等待时间。
显示图片的局部。如果一个按钮在hover和link的状态用不同的图,大多的方法是利用2个图片来实现鼠标的反馈。其实利用 background-image 和 background-position CSS属性可以实现用显示图片的局部。这样其实页面只做了一次对服务器的Request.
图片定义放在CSS中。如果显示图片的时候把图片插入到页面,这样会使得文本档尺寸增大,增加下载时间。我们可以把图片定义尽量放在缓存的CSS中,这样第一可以减少页面大小,也减少了http requests.
减少Http request是一个最好的性能优化起点。经过一些调查,百分之40-60的用户基本上是带着干净的缓存访问网站的,给他们的第一感觉一定是要页面装载迅速。
It's all about OPEN these days
最近两年,我一直在关注一些Open Source(开源)相关的信息。例如, 有关开源的项目, 开源的理念和经营模式。很多大型的公司选择项目工具的时候都会避免一些开源的项目,特别是一些桌面程应用序都会最后选择Micr*soft的解决方案。为什么他们不选择开源的语言或者Framework进行项目开发呢?可能有以下几个原因:
- 开发效率。大多开源的项目开发效率相比商业化的软件还是慢很多。对于用户来说,他们所看到的只有最后的结果,比如说他们需要一个创建历史纪录的功能,只要你们写的软件能做到这个功能,用户根本不会在乎开发人员是如何实现的。人力资源是很昂贵的,所以企业更愿意花大比的钱买license,节省开发时间。另一个问题是IDE, 大部份开源的程序缺少效率高的IDE, 企业级别的IDE支持。
- 技术支持。商业的产品大多有比较好的技术支持,如果他们提供的产品有一个严重的bug要修理,购买的license会带有高级用户的支持联系方式,一般第三方公司会在很快的时间内给你解决办法(这样项目就会承担很小的Risk)。特别是做一个大项目,用很多第三方的软件节省开发周期,那他们之间会有很多不兼容的问题,这个时候更需要技术支持。相反,开源的更需要community的支持,要看这个社区的规模,要看项目的Status(active?)。如果开源项目完全停止,那企业无法很快找到解决办法,或者根本没有办法追究责任。
- 开发人员缺乏。懂得开源程工具和framework的人比较占少数,在欧洲,高等教育选择教开源工具比较多,但是真正的工作的时候大多公司还是选择商业的解决方案。所以毕业的学生到了这些公司,开发商业化的库,end up with these skill sets. 即使有开发人员,可能真正成为expert的人也是个别的。
- 安全问题。开源的代码公开,所有的安全问题是公开的。企业当然需要隐私并且牢牢把握主安全这个窗口。
那这样,open source还有存在的意义么?或者创造开源就是那些passionate的人们的产物?如果这样想,我觉得完全是错的。相反,开源其实是非常重要的。大部分的商业产品是从开源发展出来,拿了开源的主意。拿一些最近的例子,iPhone的interaction设计是从一个大学Touch Technology衍生而来的,他们有相同的操作方法(多触点操作),有相同的, 相同的产物还有MS的Surface产品; 苹果的Mac操作系统是从开源的Linux衍生而来的; 我们现在用的Internet Address System(internet protocols-HTTP, FTP等等) 都是开源的; 挑战IE的Firefox也是开源的产物。
Open给我们带来了什么?
- Freedom。虽然没有商业支持,但是开发起来更加的自由。其实商业软件有他们的局限性。如果想做出一些新颖的东西其实是比较困难的,商业化的程序都有自己的模式,如果违反他们设计的模式开发,只会给项目带来很多麻烦。
- Standard。每商业产品都会为了版权设计自己的规范。其实这样给用户和开发人员带来很多麻烦,对技术或者任何产品的发展都是不力的。最典型的就是MS最早发布自己的HTML规范,直到现在他对公认的W3C规范负面影响很大。
- Interaction。交流是非常重要的,人们可以任意发表自己的建议,所以最后的解决方案都是用户最想要的结果,或者说是Best solution。在社区会有不同技术类型的开发人员,他们提出的建议可以让人们考虑每一个问题角度。然而商业化的,永远都是局限在一些开发人员的解决方案,他们的经验和知识都是很有局限性的。
说到这里就想起Steve Jobs在第一次被Apple开除之前的一个采访,印象很深,他说:“The only thing about ********* is, they just have no taste.” 我感觉到他说的那家公司也正在市场转型。现在的趋势,对于用户来说,单有技术是不够的,他们需要的不是技术,而是技术在现实生活种的应用。什么是应用? 应用就是User friendly。所以现在真正缺乏的是前端的工程师,他们懂得用户真正的需求。如果用商业软件,是很少有机会做出一些另人惊人的产品的。说说为什么?那我们看看一些有名的网络产品,Google(大多的内部系统都是开源的), Facebook(开源程序语言开发,并且把platform设为开源), Twitter(开源RoR的产物), Yahoo!(运用很多的开源项目开发出来的). Linux(最稳定,最受欢迎的host平台之一), Wiki(最强大的社区字典), 等等。(太多了,如果大家熟悉还有例子,可以留言)。
也许,再过不久封闭模式的开发会跟不上社区模式的进度。也许,社区模式的开发能做出更加有创意的产品。



