class Hello
@hello = "hello"
def display
puts @hello
end
end
h = Hello.new
h.display
Run Code Online (Sandbox Code Playgroud)
我创建了上面的课程.它不打印任何东西.我认为在类声明期间设置了实例变量@hello.但是当我调用display方法时输出为'nil'.这样做的正确方法是什么?
Foo = Class.new
Foo.class_eval do
def class_bar
"class_bar"
end
end
Foo.instance_eval do
def instance_bar
"instance_bar"
end
end
Foo.class_bar #=> undefined method ‘class_bar’ for Foo:Class
Foo.new.class_bar #=> "class_bar"
Foo.instance_bar #=> "instance_bar"
Foo.new.instance_bar #=> undefined method ‘instance_bar’ for #<Foo:0x7dce8>
Run Code Online (Sandbox Code Playgroud)
只是基于方法的名称,我希望class_eval允许你向Foo和instance_eval添加一个类方法,以允许你向Foo添加一个实例方法.但他们似乎反其道而行之.
在上面的例子中,如果你在Foo类上调用class_bar,你会得到一个未定义的方法错误,如果你在Foo.new返回的实例上调用instance_bar,你也会得到一个未定义的方法错误.这两个错误似乎都与对class_eval和instance_eval应该做什么的直观理解相矛盾.
这些方法之间有什么区别?
class_eval的文档:
mod.class_eval(string [,filename [,lineno]])=> obj
在mod的上下文中计算字符串或块.这可以用于向类添加方法.
obj.instance_eval {| | block} => obj
在接收器(obj)的上下文中计算包含Ruby源代码或给定块的字符串.为了设置上下文,在代码执行时将变量self设置为obj,使代码可以访问obj的实例变量.
我在Post类中有一个带有:foreign_key of post_id的Comment类.
class Comment < ActiveRecord::Base
belongs_to :post, :class_name => "Post", :foreign_key => "post_id", :counter_cache => true
belongs_to :author, :class_name => "User", :foreign_key => "author_id"
end
Run Code Online (Sandbox Code Playgroud)
但是我的CreateComments迁移没有定义数据库级外键:
class CreateComments < ActiveRecord::Migration
def self.up
create_table :comments do |t|
t.column "post_id", :integer, :default => 0, :null => false
t.column "author", :string, :default => "", :limit => 25, :null => false
t.column "author_email", :string, :default => "", :limit => 50, :null => false
t.column "content", :text, :null => false
t.column "status", :string, …
Run Code Online (Sandbox Code Playgroud) create_table :categories_posts, :id => false do |t|
t.column :category_id, :integer, :null => false
t.column :post_id, :integer, :null => false
end
Run Code Online (Sandbox Code Playgroud)
我有一个连接表(如上所述),其中的列引用了相应的类别表和posts表.我想执行的唯一约束组合键CATEGORY_ID,POST_ID在categories_posts连接表.但是Rails不支持这个(我相信).
为了避免我的数据中具有相同category_id和post_id组合的重复行的可能性,在Rails中缺少复合键的最佳解决方法是什么?
我的假设是:
如果我有一个带有a的类attr_accessor
,则默认创建一个实例变量以及相应的getter和setter.但是,有没有办法让它来创建一个类变量或类实例变量而不是创建一个实例变量?
ruby instance-variables class-variables class-instance-variables
我正在观看一个截屏视频,作者说在连接表上有一个主键是不好的,但没有解释原因.
示例中的连接表在Rails迁移中定义了两个列,并且作者为每个列添加了索引但没有主键.
为什么在这个例子中有一个主键是不好的?
create_table :categories_posts, :id => false do |t|
t.column :category_id, :integer, :null => false
t.column :post_id, :integer, :null => false
end
add_index :categories_posts, :category_id
add_index :categories_posts, :post_id
Run Code Online (Sandbox Code Playgroud)
编辑:正如我提到的Cletus,即使对于连接表,我也能理解自动编号字段作为主键的潜在用处.但是,在上面列出的示例中,作者明确避免在"create table"语句中使用语法":id => false"创建自动编号字段.通常,Rails会自动将一个auto-number id字段添加到像这样的迁移中创建的表中,这将成为主键.但是对于这个连接表,作者专门阻止了它.我不确定他为什么决定采用这种方法.
def update
@album = Album.find(params[:id])
if @album.update_attributes(params[:album])
redirect_to(:action=>'list')
else
render(:action=>'edit')
end
end
Run Code Online (Sandbox Code Playgroud)
我正在讨论的Rails 1.1.6教程建议使用update_attributes
更新模型的方法,如上面列出的控制器的示例代码中所示.看看Rails文档,我想知道为什么这个update
方法不是首选,特别是因为它的逻辑命名.
controller model ruby-on-rails updatemodel update-attributes
我试图了解何时使用self.method_name与何时使用Classname.method_name.
在下面的示例中,为什么"before_create"需要引用"User.hash_password"而不是"self.hash_password"或只是"hash_password"?
由于我们已经在User类中,我认为before_create方法将"知道""hash_password"是其自己的类的成员,并且不需要任何特殊语法来引用它.
require 'digest/sha1'
class User < ActiveRecord::Base
attr_accessor :password
attr_accessible :name, :password
validates_presence_of :name, :password
validates_uniqueness_of :name
def before_create
self.hashed_password = User.hash_password(self.password)
end
def after_create
@password = nil
end
def self.login(name, password)
hashed_password = hash_password(password || "")
self.find(:first, :conditions => ["name = ? and hashed_password = ?", name, hashed_password])
end
def try_to_login
User.login(self.name, self.password)
end
private
def self.hash_password(password)
Digest::SHA1.hexdigest(password)
end
end
Run Code Online (Sandbox Code Playgroud) 忏悔:我只对我的方法使用私人和公众可见度!
我觉得这是件坏事.但是在Rails中它似乎并不是一个问题.
有没有人在Rails中有一个例子,如果不使用受保护的可见性将是一个很大的错误?
class << self
attr_accessor :n, :totalX, :totalY
end
Run Code Online (Sandbox Code Playgroud)
上面的语法用于定义类实例变量.但是当我考虑语法含义时,它对我没有任何意义,所以我想知道这种类型的语法是否用于任何其他类型的定义.我在这里的困惑是:
class << self
Run Code Online (Sandbox Code Playgroud)
追加运算符通常意味着"向左侧的对象添加右侧的内容".但是在这个块的上下文中,如何将"将此块的内容放入类实例的定义而不是实例"?
出于同样的原因,我很困惑为什么在一个上下文类中,<< self可以定义类实例变量,而在另一个上下文它似乎创建了类变量,例如:
class Point
# Instance methods go here
class << self
# Class methods go here
end
end
Run Code Online (Sandbox Code Playgroud) ruby class-method class-variables class-instance-variables instance-methods
ruby ×5
class-method ×2
database ×2
controller ×1
foreign-keys ×1
migration ×1
model ×1
primary-key ×1
private ×1
protected ×1
public ×1
syntax ×1
updatemodel ×1