2015-05-04 4 views
1

Я использую Rails 4.2.1. В моей таблице есть столбец высоты. Есть ли способ сделать преобразование высоты в параметрах, переданных пользователем? Что-то вроде:Есть ли способ передать блок update_attributes?

class WhateverController < ApplicationController 
    def update 
    current_user.update_attributes(user_params) do |u| 
     u.height = convert_height_from_feet_to_inches 
    end 
    end 

    private 

    def user_params 
     params.require(:user).permit(:name, :height_feet, :height_inches, :weight) 
    end 

    def convert_height_from_feet_to_inches 
     (user_params[:height_feet] * 12) + user_params[:height_inches] 
    end 

end 

По какой-то причине update_attributes не обрабатывает блок, который я пытаюсь передать. Не знаете, почему вы не сможете передать блок update_attributes.

+1

Это похоже на то, что принадлежит либо помощнику вида, либо модели, а не контроллеру. – lurker

ответ

2

Вы должны сделать это в модели, а не в контроллере. Использование виртуальных атрибутов вы можете убедиться, что установка либо height_feet или height_inches обновит height с правильным значением, и наоборот:

class User < ActiveRecord::Base 
    attr_reader :height_feet, :height_inches 

    def height_feet=(feet) 
    @height_feet = feet.present? ? feet.to_i : feet 
    assign_height_from_feet_inches! 
    end 

    def height_inches=(inches) 
    @height_inches = inches.present? ? inches.to_i : inches 
    assign_height_from_feet_inches! 
    end 

    def height=(inches) 
    self.height_feet, self.height_inches = inches.divmod(12) 
    end 

    private 
    def assign_height_from_feet_inches! 
    self[:height] = 
     if self.height_feet.nil? || self.height_inches.nil? 
     nil 
     else 
     self.height_feet * 12 + self.height_inches 
     end 
    end 
end 

Теперь в контроллере вы можете просто сделать это, и все остальное будет происходить автоматически:

current_user.update_attributes(user_params) 

Это приведет к автоматическому вычислению атрибута height при каждом сохранении записи.

+0

Итак, хотя мой параметр hash не будет содержать атрибут height при вызове update_attributes, он выполнит присвоение атрибута height? – ltrainpr

+0

Справа. Поскольку 'user_params' имеет атрибуты': height_feet' и ': height_inches', Rails автоматически вызывается' User # height_feet = 'и' User # height_inches = ', которые мы определили выше. Эти методы, в свою очередь, вызывают 'assign_height_from_feet_inches!', Который устанавливает атрибут 'height'. –

+0

P.S. Вам придется решить, как вы хотите обрабатывать значения «nil». С приведенным выше кодом 'height' будет установлен на' nil', если для 'height_feet' или' height_inches' установлено значение 'nil'. Тем не менее, вы можете легко сделать так, чтобы он подсчитал 'nil' как' 0' в его вычислении. Это зависит от вас, что правильно делать в вашем случае использования. –