- 浏览: 75176 次
- 性别:
- 来自: 上海
最新评论
-
jackeyj:
不错,鼓励原创
基于Ubuntu Nginx Mongrel Mysql部署rails -
hlily2005:
threads = []
for page_to_fetch ...
ruby 笔记 -
deng131:
...
很有收获的一天 class_eval + 扩展ActiveRecord::Base -
kavinhub:
Host可以直接添TNSName:HUBTEST2 (比如) ...
配合rails的oracle连接和字符集配置
1. 前提
将局部style放到list.rhtml中,调整label浮动和固定长度,input等宽,再将左侧和右侧的select命名成不同的class,配以不同的margin-left
把form_for改成remote_form_for。这个东西相当好用.对于prototype来说,常态是使用request,简单情形才是在辅助方法里面给出:update
2. form_builder私有化
:builder => TaggedBuilder form_builder私有化,这个主意很棒
# # tagged_builder.rb # # generate like : # <p> # <label for="desc">描述</label> # <%= form.text_field 'desc'%> #</p> # class TaggedBuilder < ActionView::Helpers::FormBuilder #metapragramming to gernate method for method_name (field_helpers - %w(check_box radio_button) ).each do |selector| src = <<-END_SRC def #{selector}(field, options = {}) options[:class] ||= "biaodan" label_name=options[:label] || field.to_s @template.content_tag("p", @template.content_tag("label", label_name + ":", :for => field.to_s) + super, :id => "p"+field.to_s, :class => "pb") end END_SRC class_eval src, __FILE__, __LINE__ end end
3. 把在view中重复出现的代码塞到helpers中。
把radio_button和select+observe_field放入Helpers中,方便在view中调用
引用model中的常量并传递参数,指定remote_function
def num_select(i, form) id = 'corp_ivr_flow_n'+i.to_s s = form.select 'n'+i.to_s, @selectingnode,{:prompt => '请选择'}, :class=>"biaodan", :style => "width:100px" s += observe_field id, :url => { :action => :select_node_changed }, :with => 'n'+i.to_s end def fangshou_radio(play_mode, form) form.radio_button('play_mode', play_mode, :onclick => remote_function(:url => { :action => :change_playmode, :id => @corp_ivr_flow, :play_mode => play_mode })) end
这样在view中的调用简化成
<%=fangshou_radio(CorpIvrFlow::PLAY_MODE_PA, form)%> <%=fangshou_radio(CorpIvrFlow::PLAY_MODE_CHOICE, form)%> <%=num_select(i, form)%>
如果复杂的if可以使用“if的block化写法”
4. controller
controller中的before_filter 和 only参数,redirect时也会被再次执行,需要进一步学习cache
before_filter :get_node , :only => [:edit, :change_playmode]
如果觉得不需要有内容回应,可render nothing
render :nothing => true
使用 render :update可以在controller中直接返回类似rjs的东西
render :update do |page| page.call 'showNewNode' end
showNewNode是基于Extjs窗体的定制,然后调用。
5. 修改Extjs的图像应用链接
Extjs的s.gif是空白图像,默认竟然直接引用自extjs.com
经修改,在javascripts/adapter/prototype/ext-prototype-adapter.js中修改路径,还有在javascripts/adapter/ext/ext-base.js中也能修改,但对tree而言,是第一个起作用
6. 让Extjs.window同rails配合起来
基本思路: window可以获取html脚本中“埋伏”的元素(el),并在合适的时候显示出来。于是,这个埋伏的元素使用rails生成出来,再在需要的时候通过rjs的方式show出来。更进一步,对已show出来的window也能通过调用replace_html来重新产生显示的内容。
A. html
<div id="hello-win" class="x-hidden"> <div class="x-window-header">新建语音节点 -输入基本信息</div> <div id="hello-tabs" > <div id="newformpage" style="height:500px;"> <%= render :partial => "newform" -%> </div> </div> </div>
_newform.rhtml
通过 :html => { :id => "newform" }指定这个form的id
<% remote_form_for :corp_ivr_flow, :url => {:action => 'new', :id => @corp_ivr_flow}, :builder => TaggedBuilder, :html => { :id => "newform" } do |form| %> <input type="hidden" name="nodeid" id="nodeid" value='<%=params[:nodeid] ||= 0 %>' /> <%= render :partial => "editnode_p1", :object => form %> <% end %>
B.js
提交时,调用由rails生成的该form的onsubmit代码
function showNewNode(){ if(!win){ win = new Ext.Window({ el:'hello-win', layout:'fit', width:500, height:200, closeAction:'hide', plain: true, modal: true, items: new Ext.TabPanel({ el: 'hello-tabs', autoTabs:true, activeTab:0, deferredRender:false, border:false }), buttons: [{ text:'提交', handler: function(){ form = $('newform'); form.onsubmit(); } //disabled:true },{ text: '关闭', handler: function(){ win.hide(); } }] }); } win.show(); }
C. rails
rails主要处理两种情况:1. 操作成功后,提示用户操作完成并关闭窗口,回到主界面。
2. 操作失败,提示用户失败信息。
C1. 成功时
render :update do |page| page.call 'win.hide' # page.replace_html 'newformpage', :partial => "newform" end
C2. 先给model加上一个验证
validates_presence_of :name, :message => '必须输入节点名称'
controller中
render :update do |page| page.replace_html 'newformpage', :partial => "newform" end
更新的东西就是_newform,这里需要写入出错信息,于是又要回到rhtml那边,原先的模板里面并没有考虑出错信息。 可以使用error_messages_for 或者error_message_on。希望能把出错信息提示在form元素的最近的边上,于是又打起了helpers的主意,重新修改了私有化的form_builder
class TaggedBuilder < ActionView::Helpers::FormBuilder #metapragramming to gernate method for method_name (field_helpers - %w(check_box radio_button) ).each do |selector| src = <<-END_SRC def #{selector}(field, options = {}) options[:class] ||= "biaodan" label_name=options[:label] || field.to_s @template.content_tag("p", @template.content_tag("label", label_name + ":", :for => field.to_s) + super+ @template.error_message_on("corp_ivr_flow", field.to_s), :id => "p"+field.to_s, :class => "pb") end END_SRC class_eval src, __FILE__, __LINE__ end end
终于明白@template其实起到了<% %>的作用,而1.2.3的rails中,error_message_on不能传入实例变量,新版的似乎已经可以。查看rails代码,代码是仅按字符串再来获取对应的实例变量。
这样的话,无错误时,同原来一样,有错误时也发生了作用,但是排版很乱,于是还是要对view进行调整。
手工输入@corp_ivr_flow.errors.add(:name, 'doit') 查看出错信息。
formError是错误信息的css class,于是先把它设成行内,情况没有好转多少。于是看生成的html代码,发觉问题原来在于对错误的字段,rails会在input元素前面加上<div class="fieldWithErrors">,这样布局就乱掉了。
<p class="pb" id="pname"><label for="name">节点名称:</label><div class="fieldWithErrors"><input class="biaodan" id="corp_ivr_flow_name" label="节点名称" name="corp_ivr_flow[name]" size="10" type="text" /></div><div class="formError">doit</div></p>
修改成如下css
.formError { display: inline; } .fieldWithErrors{ display: inline; }
好了问题基本解决。
另外,也用到了一个有条件验证:
validates_numericality_of :phone_agent, :message => '必须输入数字,不得为空', :only_integer => true, :if => Proc.new { |c| c.play_mode == CorpIvrFlow::PLAY_MODE_AGENT}
7. ajax 方式提交form产生乱码
ajax提交的序列化后的form乱码 因为js的encodeURIComponent会使字符安全,碰到这种问题的人虽然有,但网上情况看来rails基本解决了这个问题,但我还是遇到了。尝试了下,可以通过URI.decode可以解码,但应该在一个filter里面解决。不过这个不是普遍现象,于是怀疑版本有问题,于是尝试升级到1.2.6(原来是1.2.3)
gem install rails -v 1.2.6 gem clean
再修改环境变量到1.2.6,然后发现在1.2.6也一样。
最后,发现是由于一个form中有两个同名的input导致。所以不是prototype封装的问题,就是rails解装的问题。但只要input不同名,那么两边配合就很正常,不会有乱码了。
8. 操作树(Extjs增加节点、删除节点,ruby对树的操作)
ruby侧操作树比较简单,只是不能直接操作parent_id,而用acts_as_nested_set提供的接口move_to_child_of等api。
Extjs侧则出乎意料的麻烦。麻烦在于,增加节点的时候,要区分是加在原先的叶节点
下面还是原先是树节点。如果原先是树节点,那么很简单,add之后了事。如果原先是叶节点,那么先要把这个东西变成树节点,然后才能加新的node。好在还有replaceChild,使得不是太烦。
增加child
function appendChild(childid, name, fatherid, isclickchild) { var child = new Ext.tree.TreeNode({ text: name, draggable:false, id: childid }); var father = getFather(fatherid); father.appendChild(child); father.expand(); var clickon ; if (isclickchild) { clickon = child; } else { clickon = father; } theTree.getSelectionModel().select(clickon); clickon.expand; tree_on(clickon, null); }
function getFather (fatherid){ if (fatherid == null || fatherid == "") { return theTree.getRootNode() } thisN = theTree.getNodeById(fatherid) if(!thisN.isLeaf()){ return thisN; } else { ppNode = thisN.parentNode; //得到要添加新节点的节点的父节点 // ppNode.removeChild(thisN); //删除当前节点 var thisNode = new Ext.tree.TreeNode({ text: thisN.text, draggable:false, id: thisN.id, leaf: false }); //创建一个非叶节点 ppNode.replaceChild(thisNode, thisN) // ppNode.appendChild(thisNode); //添加非叶节点到父节点 ppNode.expand(); } return thisNode }
remove
function removeChild(childid, name, fatherid) { var node = theTree.getNodeById(childid); node.remove(); if (fatherid !=null ) { var father = theTree.getNodeById(fatherid); father.expand(); theTree.getSelectionModel().select(father); father.expand; tree_on(father, null); } }
更新node只要setText就可以了。
9. 用flash而不是params在action与view间通信
试了下<%= text_field_tag :phoneno, flash[:phoneno], :size => 11 %>
这样比较直接比较简单。
10. 关联对象通过指定外键定义的注意事项
belongs_to :agent, :class_name => 'Agent', :foreign_key => 'phone_agent'
agent就是会成为一个属性的关联对象,外键就是phone_agent。但我开始的时候犯了个错误,把这两个定义成同名的东西了,于是我总是得不到这个foreign_key。回想一下,在coc的情况下,关联的对象和foreign_key也是不同名的。但我们往往需要同时访问这两个东西,如果定义同名的话,foreign_key作为字段会被关联对象这个属性替代(覆盖)。
11. 直接调用底层数据库连接
ActiveRecord::Base.connection.execute sql #或者CorpIvrFlow.connection.execute sql
发表评论
-
Rails 2.2 RC1发布
2008-10-24 22:27 1003国际化 线程安全 etags ruby1.9支持 文档项目 ... -
rails插件脱机下载
2008-09-19 14:03 1470在需要脱机安装gem的时候,通常介绍的方法就会无法进行。gem ... -
Resource-Based Routing
2008-08-26 09:53 1271基本增加的内容 Resource-Based Routing依 ... -
FastCGI和ruby-fastcgi运行备忘
2008-07-29 00:28 0自从拜读了ShiningRay 的ra ... -
whats new in rails2
2008-05-25 23:34 1350ActiveRecord Post.new.from_xml ... -
etexteditor + cygwin
2008-05-13 23:59 1716安装 etexteditor 安装cygwin 在cygwi ... -
升级到2.0.2
2008-04-12 14:22 1192打算把刚开始作的一个 ... -
基于Ubuntu Nginx Mongrel Mysql部署rails
2008-03-23 11:28 4471前提: 已安装好了ubuntu,此处用的是7.10版本 要做得 ... -
用RSpec来test
2008-02-18 23:03 1754http://delynnberry.com/projects ... -
很有收获的一天 class_eval + 扩展ActiveRecord::Base
2008-02-15 23:21 2501一直以来,对于一些选项类的操作,会设置常量和对应的描述。典型情 ... -
使用测试
2008-01-28 20:45 27TDD的概念听说已久,只是2年多来从未认真的这么做过。以前写后 ... -
回顾的笔记
2008-01-25 09:39 13221. ActiveSupport的笔记 2. Ac ...
相关推荐
### ASP.NET 2.0中TREEVIEW中动态增加结点 在ASP.NET 2.0中,使用TREEVIEW控件动态地从数据库中获取数据并填充到树形结构中是一项非常实用的功能。本文将详细介绍如何实现这一功能,并通过一个具体的例子来说明其...
1.若干城市的信息存入一个带头结点的单链表,结点中的城市信息包括城市名、城市的位置坐标。要求: (1)给定一个城市名,返回其位置坐标。 (2)给定一个位置坐标P和一个距离D,返回所有与P的距离小于等于D的城市。
lvm2.0 为第一版本的升级版。里面还有obj文件说明,.lef文件说明,详细源码(运行时,汇编器,链接器,调试器) 最近将对此做成一个开源项目,向着云计算、云存储方向发展。将其做成智能计算结点的核心部分! 欢迎...
这个压缩包文件“asp.net 2.0中TREEVIEW中动态增加结点.rar”显然是关于如何在运行时动态地向TreeView添加节点的教程。在ASP.NET中,这种功能非常有用,因为它允许开发者根据用户交互或后台数据变化来更新控件。 ...
本篇文章将深入探讨单循环链表的概念、特点以及如何实现带头结点和不带头结点的两种情况。 1. **单循环链表的基本概念** - **链表**:链表是一种线性数据结构,其元素(节点)在内存中不连续存放,每个节点包含...
GroupBox_ItemText.caption =结点文本 BtnSameNode.caption =新结点 BtnSubNode.caption =新子结点 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *检查框标题定义窗体* FCheckBoxCap.caption =检查框标题...
Master-Slave的数据库机构解决了很多问题,特别是read/write比较高的web2.0应用: 1、写操作全部在Master结点执行,并由Slave数据库结点定时(默认60s)读取Master的bin-log 2、将众多的用户读请求分散到更多的...
二叉树上结点的路径 二叉树是一种重要的数据结构,它在计算机科学和信息技术领域中具有广泛的应用。本文将对二叉树上结点的路径进行详细的介绍和分析。 一、什么是二叉树? 二叉树是一种特殊的树形结构,它的每个...
采用先序法建立一棵二叉树,设计输出某结点数据为x的双亲结点的数据的程序,二叉树的数据域类型为字符型, 扩展二叉树的叶子结点用‘#’表示,要求可以求一棵二叉树中多个结点的双亲。
头结点通常包含链表的长度信息,即链表中的结点个数。在我们的示例代码中,头结点的数据域用于记录链表的长度。 链表的实现 ------------ 我们的示例代码实现了一个带有头结点的链表。首先,我们定义了链表结点的...
判别结点u是否为结点v的子孙
然后,输入第一个结点信息,并判断是否为结束符“#”。如果不是虚结点,则为其申请空间,并将其加入队列 Q 中。如果是虚结点,则不需要申请空间。最后,将队列 Q 的第一个元素作为根结点返回。 二、先序遍历输出...
本文将详细讨论“带有头结点的链表”这一主题,包括它的实现、翻转和销毁过程,以及如何在实际代码中进行测试。 首先,让我们理解什么是头结点。在链表中,头结点是一个特殊的节点,它不存储任何数据,但作为链表的...
二叉树叶子结点个数计算 本文档讨论了二叉树叶子结点个数计算的问题,涵盖了二叉树的存储结构、递归算法设计、实现提示、源程序等方面。 一、存储结构 在计算二叉树叶子结点个数时,我们需要首先设计二叉树的存储...
### 只有尾结点的链表表示的队列算法 #### 1. 定义结点和队列结构 本篇文章将介绍一种利用链表实现队列的方法,该方法的特点在于只维护一个指向链表尾部(即队列尾部)的指针。这种方法在某些场景下可以有效地减少...
根据提供的文档内容,我们可以总结出以下关于使用带头结点的循环链表表示队列的数据结构算法知识点: ### 1. 循环链表定义及队列表示 #### 结点类型定义 ```c typedef int Datatype; // 定义数据类型 typedef ...
= i`来实现的,如果`k`不等于用户输入的`i`(即未到达指定位置),则表示链表中不存在该结点,此时函数会提前结束并返回错误信息。 此外,`dellist()`函数还展示了良好的内存管理习惯,即在删除结点后立即调用`free...