`
hideto
  • 浏览: 2678422 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

读Ruby for Rails的思考之method_missing

    博客分类:
  • Ruby
阅读更多
Ruby里方法的查找顺序是本类=>本类include的模块=>父类=>父类include的模块...
而当最终还是没有找到该方法时,会触发内建的method_missing方法的执行
默认的method_missing会触发异常,而我们可以通过override method_missing方法来提供一些特性
比如Rails的ActiveRecord,User.find_by_name()这个方法本来没有在User类里定义,但是可以通过override method_missing来匹配数据库fields
然后使用class_eval和send动态创建和调用查询方法

我们来看看C:\ruby\lib\ruby\gems\1.8\gems\activerecord-1.15.3\lib\active_record\base.rb中的一段代码就清除了:
 # Enables dynamic finders like find_by_user_name(user_name) and find_by_user_name_and_password(user_name, password) that are turned into
 # find(:first, :conditions => ["user_name = ?", user_name]) and  find(:first, :conditions => ["user_name = ? AND password = ?", user_name, password])
 # respectively. Also works for find(:all), but using find_all_by_amount(50) that are turned into find(:all, :conditions => ["amount = ?", 50]).
 #
 # It's even possible to use all the additional parameters to find. For example, the full interface for find_all_by_amount
 # is actually find_all_by_amount(amount, options).
   def method_missing(method_id, *arguments)
     if match = /^find_(all_by|by)_([_a-zA-Z]\w*)$/.match(method_id.to_s)
       finder, deprecated_finder = determine_finder(match), determine_deprecated_finder(match)

       attribute_names = extract_attribute_names_from_match(match)
       super unless all_attributes_exists?(attribute_names)

       attributes = construct_attributes_from_arguments(attribute_names, arguments)

       case extra_options = arguments[attribute_names.size]
         when nil
           options = { :conditions => attributes }
           set_readonly_option!(options)
           ActiveSupport::Deprecation.silence { send(finder, options) }

         when Hash
           finder_options = extra_options.merge(:conditions => attributes)
           validate_find_options(finder_options)
           set_readonly_option!(finder_options)

           if extra_options[:conditions]
             with_scope(:find => { :conditions => extra_options[:conditions] }) do
               ActiveSupport::Deprecation.silence { send(finder, finder_options) }
             end
           else
             ActiveSupport::Deprecation.silence { send(finder, finder_options) }
           end

         else
           ActiveSupport::Deprecation.silence do
             send(deprecated_finder, sanitize_sql(attributes), *arguments[attribute_names.length..-1])
           end
       end
     elsif match = /^find_or_(initialize|create)_by_([_a-zA-Z]\w*)$/.match(method_id.to_s)
       instantiator = determine_instantiator(match)
       attribute_names = extract_attribute_names_from_match(match)
       super unless all_attributes_exists?(attribute_names)

       attributes = construct_attributes_from_arguments(attribute_names, arguments)
       options = { :conditions => attributes }
       set_readonly_option!(options)

       find_initial(options) || send(instantiator, attributes)
     else
       super
     end
   end
分享到:
评论
2 楼 boobmoom 2009-09-27  
danny.chiu 写道
hideto大哥附个实例就好了,方便我们菜鸟了。
class ShowIpsController < ApplicationController
  def index
    @all_ips = ShowIp.find(:all)
    @your_ip = request.remote_ip
    unless ShowIp.find_by_ip(@your_ip)
    	ShowIp.create(:ip => @your_ip)
    end

    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @show_ips }
    end
  end

private

	def method_missing
		logger.debug { "=-=-=-=-=-=-=-=-=-=-" }
	end

end

输入http://localhost:3000/show_ips/wibble没工作,日志也没打印出来,依然是UnknownAction..

把private去掉
1 楼 danny.chiu 2009-06-14  
hideto大哥附个实例就好了,方便我们菜鸟了。
class ShowIpsController < ApplicationController
  def index
    @all_ips = ShowIp.find(:all)
    @your_ip = request.remote_ip
    unless ShowIp.find_by_ip(@your_ip)
    	ShowIp.create(:ip => @your_ip)
    end

    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @show_ips }
    end
  end

private

	def method_missing
		logger.debug { "=-=-=-=-=-=-=-=-=-=-" }
	end

end

输入http://localhost:3000/show_ips/wibble没工作,日志也没打印出来,依然是UnknownAction..

相关推荐

    ruby元编程之创建自己的动态方法

    `method_missing`是Ruby中的一个特殊方法,它在试图调用一个未定义的方法时被触发。这为开发者提供了一个机会,可以在运行时定义或处理这些方法的调用。这种机制非常适合于创建动态方法,即那些在编译时不存在但在...

    jb:用于Ruby on Rails的简单快速的JSON API模板引擎

    没有method_missing调用 带:collection选项的render_partial实际上会渲染集合(与Jbuilder不同) 句法 .jb模板应包含Ruby代码,该代码将返回任何to_json (通常为Hash或Array)的Ruby对象。 然后,返回值将to_json...

    opal-rails:将Ruby引入Rails·Opal的Rails绑定

    蛋白石路轨 Rails绑定。 ()寻找Webpack支持? :eyes: 如果要通过Webpack... method_missing = trueRails . application . config . opal . optimized_operators = trueRails . application . config . opal . arity_

    脚本编程之: ruby_bcyy_jb51.net

    6. **元编程**:Ruby的元编程特性,如`class_eval`、`instance_eval`、`method_missing`等,以及如何利用它们来增强代码的动态性。 7. **测试驱动开发(TDD)**:Ruby社区非常注重TDD,因此可能包含关于Rspec或Test::...

    ruby on rose开发文档-开发

    在Ruby on Rails中,理解Ruby的基本语法、类和对象、模块、块、 Proc和Lambda、以及元编程特性(如`send`和`method_missing`)是至关重要的。 2. **ActiveRecord**:作为Rails的ORM(对象关系映射)组件,...

    intro_to_metaprogramming:Ruby元编程简介

    使用send , define_method和method_missing遍历不同的元编程技术 将您的思维扩展到元编程,并让您考虑可以在自己的代码中利用它的地方 设置 要求 该讲习班是使用Ruby 1.9.3创建的,但是在2.1.2版本中有效。 假设您...

    Ruby中文参考手册

    7. **闭包和元编程**:Ruby的闭包(Proc和Lambda)以及动态特性(如eval、instance_variable_get/set、method_missing等)让元编程变得非常强大,允许在运行时修改和扩展代码。 8. **正则表达式**:Ruby的Regexp类...

    ruby中文教程,从基础到深入的让你学习ruby

    此外,Ruby的`send`方法可以动态调用方法,`method_missing`可以捕获未定义的方法调用。 Ruby的Gem库是其生态系统的一大亮点,提供大量的第三方库和框架,如Rails(一个流行的Web开发框架)、Sinatra(轻量级Web...

    ist的matlab代码-rails_lecture_lesson_xhtml_builder:创建一个Ruby类以使用块函数和Ruby元编程

    覆盖method_missing方法,并使用它来拦截对不存在的方法的调用。 每个不存在的方法都应成为标准的HTML标记: 例子 require 'xhtml_builder' b = XHTMLBuilder.new b.html do b.head do b.title("My Fancy Webpage") ...

    ruby metaprograming

    def self.method_missing(name, *args) puts "Called method: #{name}" end my_object = MyClass.new my_object.some_method # 输出: "Called method: some_method" ``` ##### 2. eval `eval`函数可以用来执行一...

    元编程 Ruby

    2. 方法拦截:Ruby提供了method_missing方法,它允许我们拦截对当前对象中未定义方法的调用,并进行自定义处理。 3. 模块混入:Ruby中的模块可以被包含(include)到类中,这在本质上是把模块中的方法和类混合,...

    为何Ruby 1.9的不兼容性会导致原有Ruby代码无法工作

    - **BasicObject类**:为创建代理类提供了更简洁的基类,减少了method_missing的使用。 然而,尽管Ruby 1.9提供了诸多改进,但它仍处于开发阶段,不适用于生产环境。Rails核心团队和其他gem及插件开发者正在努力...

    Ruby 语法. Ruby 是一种开源的面向对象程序设计的服务器端脚本语言

    - **元编程**:Ruby 提供了一系列方法来实现元编程,例如 `eval`、`send`、`method_missing` 等。 - **多线程**:虽然 Ruby 本身不支持原生多线程,但它提供了线程(Thread)模型来模拟并发执行。 - **性能优化**:...

    Beginning Ruby From Novice to Professional 2nd Edition.pdf

    此外,书中还会介绍Ruby的元编程能力,如`send`方法和`method_missing`,这使得Ruby在运行时可以修改自身的行为。 在“专业开发者”的部分,作者会讲解如何使用Ruby的标准库和第三方gem(Ruby的库包管理器),例如...

    ruby语言

    `class 用于自定义类的方法,`method_missing`可以捕捉未定义的方法调用。 10. **Gem包管理**:Ruby的生态系统中,Gem是包管理工具,用于分发、安装和管理Ruby库。通过Gem,开发者可以方便地使用和分享代码。 11. ...

    Ruby程序设计

    9. **Rails框架**:Ruby on Rails是Ruby最著名的Web开发框架,它采用MVC(Model-View-Controller)架构模式,提供了一套约定优于配置的开发规则,极大地提高了开发效率。 10. **元编程**:Ruby的元编程能力非常强大...

    Ruby中文教程。。。

    3. 控制结构:Ruby提供了if/else、unless、case、while、until、for等控制结构,用于实现条件判断和循环。例如,`if x &gt; 0 then puts "Positive"`。 4. 函数与方法:Ruby中函数被称为方法,可以定义在类或模块中,...

    the ruby way

    5. **元编程**:Ruby提供了`class`, `module`, `define_method`, `method_missing`等工具,允许在运行时创建和修改类和模块,实现自省和自定义行为。 6. **Gem生态系统**:Ruby拥有庞大的Gem库,这是一个开源软件包...

    Ruby语言中文教程

    `class 用于自定义类的元类,`method_missing`方法可以捕捉未定义的方法调用,从而实现动态行为。 九、Gem和Ruby生态系统 Ruby的Gem是其强大的包管理系统,开发者可以通过Gem获取和安装各种库和工具。Ruby的生态...

    Ruby中文文档.rar

    - `define_method`和`method_missing`:前者用于在运行时定义方法,后者是当尝试调用一个不存在的方法时的回调,常用于实现自定义错误处理或动态行为。 4. **模块(Module)**: - 模块用于封装相关的方法和常量...

Global site tag (gtag.js) - Google Analytics