【问题标题】:understanding the usage of cattr_accessor in Rails Model Class了解 cattr_accessor 在 Rails 模型类中的用法
【发布时间】:2017-12-05 16:13:24
【问题描述】:

我是 ruby​​ 和 rails 的新手。 在我的 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_accessorattr_accessor有什么区别?

       cattr_accessor :form_steps do
       %w(identity characteristics instructions)
       end
       attr_accessor :form_step

2)为什么两个不同的符号(:form_steps:form_step)分别用作cattr_accessorattr_accessor方法的方法参数?

3) 为什么将块作为参数传递给cattr_accessor 方法?

非常感谢任何帮助。谢谢

【问题讨论】:

标签: ruby-on-rails ruby wicked-gem


【解决方案1】:

首先,此方法已被弃用或移动。 您使用哪个版本,Rails 4 还是 Rails?

cattr_accessor > 替换为mattr_accessor(*syms, &amp;blk)Module,它是类Class 的超类。我建议使用 attr_accessor,它只是一种设置类属性的方法,它的作用类似于类的 getter 或 setter,但仅适用于实例(在内存中),属性是保存在任何地方。

cattr_accessor 类似于attr_* 方法,但用于类级别。您不会想到的一件事是因为它使用了支持 @@form_steps,即类和所有实例之间共享的值。

API 文档:

为类属性定义类和实例访问器。

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]

如果子类更改了值,那么这也会更改父类的值。同样,如果父类改变了值,那么子类的值也会改变。

class Male < Person
end

Male.hair_colors << :blue
Person.hair_colors # => [:brown, :black, :blonde, :red, :blue]

要退出实例编写器方法,请传递 instance_writer: false。要退出实例读取器方法,请传递 instance_reader: false。

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

您也可以传递一个块来设置具有默认值的属性。

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]

1)

  • attr_accessor:是一种 ruby​​ 方法,它可以生成 getter 和 setter
  • cattr_accessor:是一个 ruby​​ 方法,它为类创建一个 getter 和一个 setter(很奇怪)。

2) 类变量倾向于在类之间徘徊。 @@form_steps 类变量可以通过继承树暴露出来。

3) 设置哪些属性会有这个类。 form_steps

p = Pet.new
p.form_steps = "var"

并在当前实例 Pet 中使用 form_steps 属性(就像在方法 required_for_step? 中所做的那样)。

【讨论】:

    猜你喜欢
    • 2018-09-10
    • 1970-01-01
    • 1970-01-01
    • 2015-01-14
    • 2015-01-23
    • 1970-01-01
    • 2017-10-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多