简体   繁体   English

在rails模型类中attr_accessor的用法

[英]usage of attr_accessor in a rails model class

Excuse me for the noob question.I am a newbie to ruby and rails and Needed some help in Understanding the attr_accessor which I have come across in the code 请问一个菜鸟问题。我是ruby和rails的新手,需要一些帮助来理解代码中遇到的attr_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

model 模型

 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

and

      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

routes 路线

  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) what I all only know about attr_accessor is, it nothing more than a getter/setter for an object.I do not have a form_step as an attribute of my Pet Model(pets table).But in the model, there is attr_accessor :form_step .How is getter/setter generated to :form_step ? 1)我对attr_accessor唯一了解的只是对象的getter / setter,我没有form_step (pets table)的form_step属性,但是在模型中有attr_accessor :form_step将getter / setter生成为:form_step

2) Is :form_step an object of Pet class? 2) :form_step是Pet类的对象吗?

I am not totally understanding the usage of attr_accessor method in Rails model class. 我不完全了解Rails模型类中attr_accessor方法的用法。

3) Kindly explain me a scenario where I must generate getter/setter for Model attributes (pets table attributes or fields) 3)请向我解释一个场景,其中我必须为Model属性(pets表属性或字段)生成getter / setter

eg: attr_accessor :name attr_accessor :colour ..etc 例如: attr_accessor :name attr_accessor :colour

when do we use attr_accessor for model attributes or fields? 何时将attr_accessor用于模型属性或字段?

Lets starts with OOPs, basically class is template which defines properties and behavior of its instances ie objects. 让我们从OOP开始,基本上, class是定义其实例(即对象)的属性和行为的模板。

The rails model also a ruby class. 滑轨模型也是红宝石类。 Its properties are being defined by attr_accessor and behaviors are defined by static and instance methods . 它的属性由attr_accessor定义,行为由static and instance methods定义。

Consider a class with attr_accessor 考虑一个with attr_accessor的类

class Animal
      //defines animal properties
      attr_accessor :legs
      //defines animal behavior
      def talk
      end
end

and without attr_accessor 并且without attr_accessor

class Animal
      //defines animal properties
      //getter
      def legs
        @legs
      end
      //setter
      def legs=(value)
        @legs = value
      end

      //defines animal behavior
      def talk
      end
end

Both representations are exactly same. 两种表示完全相同。 The attr_accessor automatically add getter and setter for us and makes the life of developer easier. attr_accessor自动为我们添加getter和setter,并使开发人员的工作更加轻松。

Lets answer you questions 让我们回答您的问题

  1. Ruby attr_accessor automatically adds these for you as explained earlier. Ruby attr_accessor自动为您添加这些,如前所述。

  2. form_step its a attribute of Pet class and can be accessed as petObj.form_step . form_stepPet class的属性,可以作为petObj.form_step访问。

  3. If table is associated/mapped with Model, then you don't have to define columns in tables as attr_accessor , Rails automatically takes care for you. 如果表与模型相关联/映射,则不attr_accessor表中的列定义为attr_accessor ,Rails会自动为您服务。 If field or attribute not exists in table, then you need to manually define it as attr_accessor in Model . 如果表中不存在字段或属性,则需要在Model attr_accessor其手动定义为attr_accessor

I hope this answers your question. 我希望这回答了你的问题。

Part of the Rails' magic is that when you have a class Pet and a table pets, you get the accessors for all the columns in the table for free. Rails的神奇之处在于,当您拥有一个Pet类和一个表pets时,可以免费获得表中所有列的访问器。 It's as if you've declared attr-accessor for all of them, only you don't need to. 就像您已经为所有它们都声明了attr-accessor一样,只是您不需要。

In your example, #form_step is not created in the table. 在您的示例中,未在表中创建#form_step But it is declared using attr_accessor . 但是它是使用attr_accessor声明的。 It works just like plain old ruby. 它的作用就像普通的红宝石一样。 This gives you a getter/setter (answer to your Q1). 这为您提供了一条吸气剂/吸气剂(Q1的答案)。

It's an instance method of Pet class. 这是Pet类的实例方法。 You call it on a Pet object, like Pet.new.form_step = 5 (answer to Q2). 您可以在Pet对象上调用它,例如Pet.new.form_step = 5 (问题2的答案)。

But you can't persist whatever value you assign to #form_step to db. 但是您无法将分配给#form_step任何值#form_step给db。 So the answer to Q3 is that you usually do this when you need to pass some messages (ie call methods) between your objects, but you don't need to persist them to db. 因此,对第3季度的回答是,通常在需要在对象之间传递某些消息(即调用方法)时执行此操作,而无需将它们持久化到db。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM