2017-09-25 2 views
0

J'ai une forme où un utilisateur tape une valeur monétaire comme 6.50Rails-modification d'un imbriqué dans le contrôleur param

Lorsque l'enregistrement est en cours d'enregistrement, je veux enregistrer en cents comme 650.

Comment puis-je changer le param

center: { ticket_attributes: { value: '6.50' } }

à

center: { ticket_attributes: { value: '650' } }

Dans la méthode update? Je ne peux pas changer dans le modèle le champ int va déjà couper le .50

+0

Fournissez le code de contrôleur complet s'il vous plaît. –

+0

C'est une mauvaise pratique d'ajouter des solutions de contournement comme celle-ci. Des choses comme celle-ci peuvent vous conduire à des situations différentes qui seront difficiles à déboguer un peu plus tard. Pourquoi ne pas simplement modifier votre colonne dans db pour stocker les flottants et lancer la migration qui va modifier vos entiers en flottants? – Avdept

Répondre

0

Essayez ceci:

def method_where_you_want_to_change_params 
    if resource_params[:resource_name].present? 
    new_ticket_attributes = resource_params[:ticket_attributes] 
    param_to_change = new_ticket_attributes[:value] 
    param_to_change = params_to_change * 100 
    new_ticket_attributes[:value] = param_to_change 
    end 

    modified_params = resource_params 
        .except(:ticket_attributes) 
        .merge(:new_ticket_attributes) 

    # work with your resource as you need, create or modify 
    # for example 
    @resource = resource_class.new modified_params 
end 

protected 

def resource_params 
    params.permit(... list of your params, as usual...) 
end 
0

Oui, il est bien de le faire dans la méthode update. Gardez à l'esprit, que puisque vous utilisez strong-parameters vous ne devriez pas changer le hachage params lui-même. , Résultat du changement des paramètres au lieu de hachage après sa liste blanche par strong-parameters:

class TicketsController < ApplicationController 

    def update 
    # first, get whitelisted params 
    update_params = update_ticket_params 
    # then perform convertion 
    update_params[:value] = value_in_cents(update_params[:value]) 

    @ticket.update(update_params) 
    # ... 
    end 

    private 

    def update_ticket_params 
    params.require(:ticket).permit(:value, ...) 
    end 

    def value_in_cents(value_in_dollars) 
    # TODO: convert dollars to cents 
    end 
end 

Pour une meilleure compréhension de ce dont je parle et les problèmes possibles, voir ce (Modify ruby hash in place(rails strong params))

Une autre approche

Vous peut convertir la valeur au niveau du modèle en utilisant l'attribut virtuel. Chaque fois que vous définissez l'attribut virtuel (qui est :value_in_dollars), il permet de convertir et d'attribuer value attribut:

class Ticket < ApplicationRecord 
    attr_accessor :value_in_dollars 

    # whenever you set :value_in_dollars, it converts and assigns :value 
    def value_in_dollars=(value) 
    self.value = value_in_cents(value) 
    end 

    private 

    def value_in_cents(value_in_dollars) 
    # TODO: convert dollars to cents 
    end 
end 

En utilisant cette approche, vous pouvez passer votre valeur en tant que value_in_dollars de la forme. Le contrôleur ressemblera à ceci:

class TicketsController < ApplicationController 

    def update 
    @ticket.update(update_ticket_params) 
    # ... 
    end 

    private 

    def update_ticket_params 
    # expect 'value_in_dollars' value from the form, not 'value' 
    params.require(:ticket).permit(:value_in_dollars, ...) 
    end 
end