我想在Yii2中编写类似行为的内容,因此我不仅需要模块,还需要选项来定义它的工作方式。
我需要的例子:
class User
include FullNameModule
show_full_lastname false
...
end
我在Paperclip gem中看到了这样的情况:
class User < ActiveRecord::Base
attr_accessible :avatar
has_attached_file :avatar, styles: { medium: "300x300>", thumb: "100x100>" }, default_url: "/images/:style/missing.png"
validates_attachment_content_type :avatar, content_type: /\Aimage\/.*\Z/
end
我现在拥有的东西:
module FullNameModule
def full_name
if show_full_lastname
"#@name #@last_name"
else
"#@name #{@last_name[0]}."
end
end
def self.included klass
klass.extend ClassMethods
end
def show_full_lastname
self.class.instance_variable_get('@show_full_lastname')
end
module ClassMethods
def show_full_lastname b
@show_full_lastname = b
end
end
end
class User
include FullNameModule
show_full_lastname false
def initialize params
@name = params[:name]
@last_name = params[:last_name]
end
end
user = User.new ({name: 'John', last_name: 'Tailor'})
p user.full_name
它运作正常,但看起来有点难看,这是正确的方法吗?
答案 0 :(得分:1)
为什么要在模块中编写“类方法”?您应该为类方法编写一个单独的类并编写它,以便模块可以包含在类中,然后使类用户继承该类。我真的不明白这个
的目的def self.included klass
klass.extend ClassMethods
end
任一。模块将在多个类中使用,而类用于单个继承。你实际上甚至不需要“ClassMethods”来处理这个问题。这是一个更好的方法;
---编辑----
实际上,你使这种方式变得比它需要的更复杂。在对代码进行了30分钟的讨论之后,这就是我想出来的。
module FullNameModule
def name(b)
if b == true
return "#@name #@last_name"
else
return "#{@name} #{@last_name[0]}."
end
end
end
class User
include FullNameModule
def initialize params
@name = params[:name]
@last_name = params[:last_name]
end
end
user = User.new ({name: 'John', last_name: 'Tailor'})
p user.name(false)