我是红宝石和铁轨的新手。 在我的Rails应用程序中,我正在尝试使用Wicked Wizard gem并且需要一些帮助来理解我在代码中遇到的cattr_accessor
create_table "pets", force: :cascade do |t|
t.string "name"
t.string "colour"
t.string "owner_name"
t.text "identifying_characteristics"
t.text "special_instructions"
t.datetime "created_at"
t.datetime "updated_at"
t.string "email"
t.string "password"
end
模型
class Pet < ActiveRecord::Base
has_many :pet_photos
cattr_accessor :form_steps do
%w(identity characteristics instructions)
end
attr_accessor :form_step
validates :email, presence: true
validates :name, :owner_name, presence: true, if: -> { required_for_step?(:identity) }
validates :identifying_characteristics, :colour, presence: true, if: -> { required_for_step?(:characteristics) }
validates :special_instructions, presence: true, if: -> { required_for_step?(:instructions) }
def required_for_step?(step)
return true if form_step.nil?
return true if self.form_steps.index(step.to_s) <= self.form_steps.index(form_step)
end
end
和
class Pet::StepsController < ApplicationController
include Wicked::Wizard
steps *Pet.form_steps
def show
@pet = Pet.find(params[:pet_id])
render_wizard
end
def update
@pet = Pet.find(params[:pet_id])
@pet.update(pet_params(step))
if params[:images]
params[:images].each do |image|
@pet.pet_photos.create(image: image)
end
end
render_wizard @pet
end
private
def pet_params(step)
permitted_attributes = case step
when "identity"
[:name, :owner_name]
when "characteristics"
[:colour, :identifying_characteristics]
when "instructions"
[:special_instructions]
end
params.require(:pet).permit(permitted_attributes).merge(form_step: step)
end
end
路由
PetThing::Application.routes.draw do
resources :pets, only: [:new, :create, :index, :destroy] do
resources :steps, only: [:show, :update], controller: 'pet/steps'
end
root to: 'pets#index'
现在我的问题是
1) cattr_accessor
和attr_accessor
之间有什么区别?
cattr_accessor :form_steps do
%w(identity characteristics instructions)
end
attr_accessor :form_step
2)为什么两个不同的符号(:form_steps
,:form_step
)分别用作cattr_accessor
和attr_accessor
方法的方法参数?< / p>
3)为什么将一个块作为参数传递给cattr_accessor
方法?
任何帮助都是高度赞赏的。谢谢你
答案 0 :(得分:4)
首先,不推荐使用此方法或移动此方法。 您使用的是哪个版本,Rails 4还是Rails?
cattr_accessor
&gt;已替换为mattr_accessor(*syms, &blk)
的{{1}},这是类Module
的超类。我建议使用 attr_accessor ,这只是一个为类设置属性的方法,它的作用类似于类的getter或setter,但只适用于实例(在内存中),属性是保存在任何地方。
Class
与cattr_accessor
方法类似,但适用于类级别。您不希望的一件事是因为它使用了支持attr_*
,即类和所有实例之间共享的值。
为类属性定义类和实例访问器。
@@form_steps
如果子类更改了值,那么这也会更改父类的值。同样,如果父类更改了值,那么也会改变子类的值。
module HairColors
mattr_accessor :hair_colors
end
class Person
include HairColors
end
Person.hair_colors = [:brown, :black, :blonde, :red]
Person.hair_colors # => [:brown, :black, :blonde, :red]
Person.new.hair_colors # => [:brown, :black, :blonde, :red]
要退出实例编写器方法,请传递instance_writer:false。要选择退出实例读取器方法,请传递instance_reader:false。
class Male < Person
end
Male.hair_colors << :blue
Person.hair_colors # => [:brown, :black, :blonde, :red, :blue]
或通过module HairColors
mattr_accessor :hair_colors, instance_writer: false, instance_reader: false
end
class Person
include HairColors
end
Person.new.hair_colors = [:brown] # => NoMethodError
Person.new.hair_colors # => NoMethodError
,选择退出两种实例方法。
instance_accessor: false
此外,您可以传递一个块以使用默认值设置属性。
module HairColors
mattr_accessor :hair_colors, instance_accessor: false
end
class Person
include HairColors
end
Person.new.hair_colors = [:brown] # => NoMethodError
Person.new.hair_colors # => NoMethodError
<强> 1)强>
<强> 2)强> 类变量倾向于从一个类到另一个类。 @@ form_steps类变量可以通过继承树公开。
3)设置具有此类的属性。 module HairColors
mattr_accessor :hair_colors do
[:brown, :black, :blonde, :red]
end
end
class Person
include HairColors
end
Person.class_variable_get("@@hair_colors") #=> [:brown, :black, :blonde, :red]
form_steps
并使用当前实例Pet中的p = Pet.new
p.form_steps = "var"
属性(就像您在方法form_steps
中所做的那样)。