Próbowałem podobnej konstrukcji w Rails 4, ale nie przeszło
Więc z Guidem przerobiłem kod na coś takiego:
def create
Post.create(post_params)
end
private
def post_params
params.require(:post).permit(:title)
end
Sęk w tym, że nie bardzo rozumiem ten zapis. Co się dzieje pod maską? I właściwie po co coś takiego? Jaka bya wada tego prostego rozwiązania w Rails 3?
W rails 3 było coś takiego jak attr_accessible i atrybuty, które chciałeś ustawić za pomocą hasha musiałeś umieszczać w attr_accessible, co uniemożliwiało ustawienie (np. z poziomu konsoli) pozostałych atrybutów za pomocą hasha (mass assignment).
Tak samo, z różnych kontrolerów teoretycznie można by ustawić różne parametry/atrybutów konkretnego modelu, np. różny poziom dostęp itd, a ustawiając attr_accessible ustawiasz tak jakby globalnie (dla konkretnego modelu) co można ustawić przez mass assignment a czego nie można.
Cały ten mechanizm jest po to, aby programista sam decydował jakie parametry są dopuszczalne. Gdyby nie było nic takiego, ktoś mógłby przykładowo zmodyfikować sobie formularz Firebugiem i przesłać dodatkowy (niebezpieczny) parametr typu user_id, password i tym podobne i w ten sposób namieszać nam w bazie dosyć konkretnie. Swojego czasu miał z tym problem m.in github.
Dlatego w Rails 3 wprowadzono coś takiego jak attr_attributes, gdzie na poziomie modelu to deklarowałeś, co dalej wiązało się z wieloma problemami, bo było to globalne per model.
Strong parameters pozwala na definiowanie akceptowanych parametrów per akcja/kontroler, co daje już pełną swobodę i bezpieczeństwo. A to, że trzeba napisać kilka linijek więcej… cóż, coś za coś
To nie kwestia tego, że parametrem jest :id, a że metodą jest .find. W tym przypadku nie ma problemu z mass assignment - nikt nie jest w stanie ci zmienić niczego w bazie poprzez find (o ile nie ma problemu z SQL injection, ale to inna bajka). Zabezpieczenia przed mass assignment sprawdzają metody zmieniające atrybuty modelu - np. .create, #attributes=, #update, etc.