29

Czy jest jakiś sposób w strong parameters, aby zezwolić na wszystkie atrybuty modelu nested_attributes modelu? Oto przykładowy kod.mocne parametry zezwalają na wszystkie atrybuty zagnieżdżonych atrybutów

class Lever < ActiveRecord::Base 
has_one :lever_benefit 
accepts_nested_attributes_for :lever_benefit 
end 

class LeverBenefit < ActiveRecord::Base 
    # == Schema Information 
    # id   :integer   not null, primary key 
    # lever_id :integer 
    # explanation :text 
end 

Dla parametrów dźwigni silny Piszę obecnie ten

def lever 
params.require(:lever).permit(:name,:lever_benefit_attributes => [:lever_id, :explanation]) 
end 

Czy istnieje sposób na zagnieżdżonych atrybutów mogę napisać, aby umożliwić wszystkie atrybuty bez wyraźnie dając atrybuty nazwać jak lever_id i explanation?

Uwaga: Proszę nie pomylić z tym pytaniem z permit! lub permit(:all) to dla umożliwiającą wszystkim dla zagnieżdżonych atrybutów

+0

spróbować przeczytaniu tej odpowiedzi może być to pomocne. > http://stackoverflow.com/questions/14483963/rails-4-0-strong-parameters-nested-attributes-with-a-key-that-points-to-a-hash –

+0

dzięki, ale widziałem to . Jeśli zauważysz, że robi to samo z selektywnym filtrowaniem atrybutów ("assets_attributes:: nazwa_pliku"), który przekazuje nazwę pliku. Chcę zezwolić na wszystkie parametry dla atrybutów zagnieżdżonych – AnkitG

Odpowiedz

10

Sensem mocnych parametrów jest w nazwie: uczynić swoje parametry wejściowe silny.
Zezwalanie na wszystkie parametry byłoby bardzo złym pomysłem, ponieważ pozwoliłoby to każdemu wprowadzić wartości, które niekoniecznie chcą być aktualizowane przez użytkowników.

W podanym przykładzie podaje się dwa parametry, które obecnie należy podać:
[:lever_id, :explanation].

Jeśli zezwoliłeś na wszystkie parametry, możliwe jest, że ktoś zmieni dowolną inną wartość.
created_at lub lever_id na przykład.

Z pewnością stanowiłoby to problem bezpieczeństwa, dlatego nie należy tego robić.
Wyraźne określenie wszystkich atrybutów może wydawać się nudne, gdy to zrobisz.
Jest to jednak konieczne, aby zapewnić bezpieczeństwo aplikacji.

Edytuj: Dla osób, które nie chcą tego zrobić. To nie może być odpowiedź, której szukasz, ale jest to odpowiedź, której potrzebujesz.
Białe listy wszystkich atrybutów zagnieżdżonych to ogromna luka w zabezpieczeniach, którą próbują chronić silne paramery, i usuwasz ją.
Spójrz na to, co prowadzi do budowania strong_params, a jak nie przy użyciu to może być złe dla Ciebie: https://gist.github.com/peternixey/1978249

+1

dziękuję, twoja odpowiedź jest słusznym punktem, że może to być problemem bezpieczeństwa. Pójdę z wyraźnym wspomnieniem o atrybutach. – AnkitG

+17

Jeśli otrzymany skrót jest przechowywany w zserializowanej kolumnie JSON, nie ma żadnych obaw związanych z bezpieczeństwem dla kluczy. (Inne niż istniejące obawy dotyczące zbyt dużych danych wejściowych). Mam ten przypadek użycia i chciałbym zezwolić na dowolny dowolny klucz w haszyszu. –

+2

Istnieją inne sposoby zabezpieczania atrybutów. Obiekty komend, które rzucają niedozwolone parametry, są na przykład znacznie lepszym rozwiązaniem, IMHO. – karmajunkie

46

Jedyna sytuacja ja spotkałem gdzie umożliwiając dowolne klawisze w zagnieżdżonych params hash uzasadnione wydaje mi się podczas pisania do zserializowanej kolumny. Udało mi się nią tak:

class Post 
    serialize :options, JSON 
end 

class PostsController < ApplicationController 
    ... 

    def post_params 
    all_options = params.require(:post)[:options].try(:permit!) 
    params.require(:post).permit(:title).merge(:options => all_options) 
    end 
end 

try pilnuje, nie wymagamy prezenty z kluczem :options.

+0

Dziękuję bardzo, oszczędzasz moje dużo czasu :) –

+1

To jest poprawna odpowiedź! zasługujesz na zielone pole wyboru! –

+2

Dlaczego 'params.require (: post) .fetch (: options, nil)' zamiast 'params.require (: post) [: options]'? –

5

spróbować

params.require(:lever).permit(:name, leave_benefit_attributes: LeaveBenefit.attribute_names.collect { |att| att.to_sym }) 
10

Po pierwsze, upewnij się, że naprawdę chcesz, aby wszystkie wartości w zagnieżdżonych hash. Zapoznaj się z Damien MATHIEU's answer, aby zrozumieć potencjalne otwarcie luk w zabezpieczeniach ...

Jeśli nadal potrzebujesz/chcesz zezwolić na wszystkie wartości w haszsie (istnieją do tego całkowicie ważne przypadki użycia, np. Przechowywanie nieustrukturyzowanych metadanych dostarczonych przez użytkownika dla danego rekordu), możesz to osiągnąć za pomocą następujących fragmentów kodu :

def lever_params 
    nested_keys = params.require(:lever).fetch(:lever_benefit_attributes, {}).keys 
    params.require(:lever).permit(:name,:lever_benefit_attributes => nested_keys) 
end 

Uwaga: to jest bardzo podobna do tf.'s answer, ale nieco bardziej eleganckich, ponieważ nie będzie żadnych Unpermitted parameters: lever_benefit_attributes ostrzeżeń/błędów.

15

Właściwie istnieje sposób na białe listy wszystkich parametrów zagnieżdżonych.

params.require(:lever).permit(:name).tap do |whitelisted| 
    whitelisted[:lever_benefit_attributes ] = params[:lever][:lever_benefit_attributes ] 
end 

Ta metoda ma przewagę nad innymi rozwiązaniami. Umożliwia zezwolenie na zagnieżdżone parametry.

Podczas gdy inne rozwiązania, takie jak:

nested_keys = params.require(:lever).fetch(:lever_benefit_attributes, {}).keys 
params.require(:lever).permit(:name,:lever_benefit_attributes => nested_keys) 

nie uwagi.


Źródło:

https://github.com/rails/rails/issues/9454#issuecomment-14167664

+2

Nie będzie działać dla zagnieżdżonych params w Rails 5. Zobacz, dlaczego tutaj: http://eileencodes.com/posts/actioncontroller-parameters-now-returns-an-object-instead-of-a-hash/ – rmcsharry

Powiązane problemy