wash

          Accessing Attributes

          If a model object has an attribute named balance, you can access the
          attribute’s value using the indexing operator, passing it either a string or
          a symbol. Here we’ll use symbols.
          account[:balance] #=> return current value
          account[:balance] = 0.0 #=> set value of balance
          However, this is deprecated in normal code, as it considerably reduces
          your options should you want to change the underlying implementation
          of the attribute in the future. Instead, you should access values or model
          attributes using Ruby accessor methods.
          account.balance #=> return current value
          account.balance = 0.0 #=> set value of balance
          The value returned using these two techniques will be cast by Active
          Record to an appropriate Ruby type if possible (so, for example, if the
          database column is a timestamp, a Time object will be returned). If you
          want to get the raw value of an attribute, append _before_type_cast to the
          method form of its name, as shown in the following code.

          COLUMNS AND ATTRIBUTES 195
          David Says. . .
          Overriding Model Attributes
          Here’s an example of the benefits of using accessors to get at the
          attributes of models. Our account model will raise an exception immediately
          when someone tries to set a balance below a minimum value.
          class Account < ActiveRecord::Base
          def balance=(value)
          raise BalanceTooLow if value < MINIMUM_LEVEL
          self[:balance] = value
          end
          end
          account.balance_before_type_cast #=> "123.4", a string
          account.release_date_before_type_cast #=> "20050301"
          Finally, inside the code of the model itself, you can use the read_attribute( )
          and write_attribute( ) private methods. These take the attribute name as a
          string parameter.
          Boolean Attributes
          Some databases support a boolean column type, others don’t. This makes
          it hard for Active Record to abstract booleans. For example, if the underlying
          database has no boolean type, some developers use a char(1) column
          containing “t” or “f” to represent true or false. Others use integer columns,
          where 0 is false and 1 is true. Even if the database supports boolean types
          directly (such as MySQL and its bool column type), they might just be
          stored as 0 or 1 internally.
          The problem is that in Ruby the number 0 and the string “f” are both
          interpreted as true values in conditions.4 This means that if you use the
          value of the column directly, your code will interpret the column as true
          when you intended it to be false.
          # DON'T DO THIS
          user = Users.find_by_name("Dave")
          if user.superuser
          grant_privileges
          end
          4Ruby has a simple definition of truth. Any value that is not nil or the constant false is
          true.

          To query a column in a condition, you must append a question mark to
          the column’s name.
          # INSTEAD, DO THIS
          user = Users.find_by_name("Dave")
          if user.superuser?
          grant_privileges
          end
          This form of attribute accessor looks at the column’s value. It is interpreted
          as false only if it is the number zero; one of the strings "0", "f", "false",
          or "" (the empty string); a nil; or the constant false. Otherwise it is interpreted
          as true.
          If you work with legacy schemas or have databases in languages other than
          English, the definition of truth in the previous paragraph may not hold.
          In these cases, you can override the built-in definition of the predicate
          methods. For example, in Dutch, the field might contain J or N (for Ja or
          Nee). In this case, you could write
          class User < ActiveRecord::Base
          def superuser?
          self.superuser == 'J'
          end
          # . . .
          end
          Storing Structured Data
          It is sometimes convenient to store attributes containing arbitrary Ruby
          objects directly into database tables. One way that Active Record supports
          this is by serializing the Ruby object into a string (in YAML format) and
          storing that string in the database column corresponding to the attribute.
          In the schema, this column must be defined as type text.
          Because Active Record will normally map a character or text column to a
          plain Ruby string, you need to tell Active Record to use serialization if you
          want to take advantage of this functionality. For example, we might want
          to record the last five purchases made by our customers. We’ll create a
          table containing a text column to hold this information.
          File 6 create table purchases (
          id int not null auto_increment,
          name varchar(100) not null,
          last_five text,
          primary key (id)
          );
          In the Active Record class that wraps this table, we’ll use the serialize( )
          declaration to tell Active Record to marshal objects into and out of this
          column.
          File 8 class Purchase < ActiveRecord::Base
          serialize :last_five
          # ...
          end
          When we create new Purchase objects, we can assign any Ruby object to
          the last_five column. In this case, we set it to an array of strings.
          File 8 purchase = Purchase.new
          purchase.name = "Dave Thomas"
          purchase.last_five = [ 'shoes', 'shirt', 'socks', 'ski mask', 'shorts' ]
          purchase.save
          When we later read it in, the attribute is set back to an array.
          File 8 purchase = Purchase.find_by_name("Dave Thomas")
          pp purchase.last_five
          pp purchase.last_five[3]
          This code outputs
          ["shoes", "shirt", "socks", "ski mask", "shorts"]
          "ski mask"
          Although powerful and convenient, this approach is problematic if you
          ever need to be able to use the information in the serialized columns outside
          a Ruby application. Unless that application understands the YAML
          format, the column contents will be opaque to it. In particular, it will be
          difficult to use the structure inside these columns in SQL queries. You
          might instead want to consider using object aggregation, described in Section
          15.2, Aggregation, on page 247, to achieve a similar effect.

          posted on 2006-05-11 11:09 wash 閱讀(203) 評論(0)  編輯  收藏 所屬分類: ruby rails

          主站蜘蛛池模板: 乌拉特后旗| 乳源| 古浪县| 尼玛县| 崇左市| 夏津县| 三台县| 东宁县| 祁连县| 荃湾区| 右玉县| 德安县| 上蔡县| 九龙县| 富宁县| 修文县| 边坝县| 娄底市| 吉水县| 林甸县| 青龙| 乡城县| 桓台县| 长宁区| 高碑店市| 勐海县| 桐庐县| 扶绥县| 浑源县| 灵山县| 徐汇区| 虞城县| 晋宁县| 无极县| 福安市| 衡南县| 花垣县| 淅川县| 凤凰县| 赣州市| 阳谷县|