1

У меня есть вложенный ресурс в моем routes.rbОбновление действия для вложенного ресурса в Rails

# routes.rb 
resources :users do 
    resource :preferences, :only => [:create,:show,:update,:destroy] 
end 

Теперь обновить предпочтения пользователя, я использую

preferences = Preference.where(:user_id => user_id).update_all(preferences_request) 
render json: preferences, status: 200 

Но я чувствую не рекомендуется использовать update_all, поскольку каждый пользователь имеет только одно предпочтение. А также я не могу использовать render :json => preferences, так как preferences будет иметь значение 1 вместо фактического хеш-объекта со всеми атрибутами таблицы. Каков наилучший способ обновления предпочтений?

ответ

1

Просто загрузите предпочтительнее, а затем выполните команду update.

preference = Preference.find_by!(user_id: user_id) 
preference.update(preferences_request) 

render json: preference 

Вы должны иметь дело со случаем запрос возвращает ноль (потому что пользователь не существует, к примеру). preferences_request должен быть хэш attributes => values. Конечно, вы можете также проверить его и/или использовать функцию сильных параметров для фильтрации наших атрибутов, которые вы не хотите обновлять.

+2

'Preference.where (user_id: user_id) .take' может быть заменен на' Preference.find_by! (User_id: user_id) 'для краткости. :-) – Drenmi

+1

Это имеет смысл, я обновил ответ @Drenmi. Благодарю. –

1

Кажется, у вас есть инструкция по 1-1 Предпочтения со следующим кодом:

class User < ActiveRecord::Base 
    has_one :preference 
end 

class Preference < ActiveRecord::Base 
    belongs_to :user 
end 

В соответствии с API методом update_all предназначены для обновления связанных объектов в пакете прямо через слой базы данных обводного ActiveRecord:

Обновляет все записи в текущей связи с данными. Этот метод строит один оператор SQL UPDATE и отправляет его в базу данных прямо . Он не создает экземпляры задействованных моделей, и он не активирует обратные вызовы или проверки Active Record. Значения, прошедшие , равны update_all, не будут проходить поведение типа ActiveRecord . Он должен получать только значения, которые могут быть переданы как: базы данных SQL.

Но, вероятно, вам нужно передать объекты через проверки и возвращать объекты туда, где обновление метод может удовлетворить ваши потребности лучше, см API:

обновляет объект (или несколько объектов) и сохраняет его к базе данных, , если проверки пройдут. Получаемый объект возвращается, если объект был успешно сохранен в базе данных или нет.

На ваш вопрос, у вас есть отображение 1-1, поэтому нет необходимости обновлять несколько записей. Исправьте меня, если я ошибаюсь:

class PreferencesController 
    def update 
    preference = User.find(params[:id]).preference 
    preference.update(params[:preference]) 
    return json: preference.as_json 
    end 
end 
1

Обычно с таким запросом вы делаете два запроса. Один, чтобы найти User и еще один, чтобы обновить его.

Ваш запрос должен быть в URL users/1/preferences (заменить 1 с идентификатором пользователя, который вы пытаетесь обновить)

Затем контроллер код может выглядеть

def update 
    user = User.find(params[:user_id]) 
    user.preferences.update!(preference_request) 
    render json: user.preferences 
end 

на благо делать это это это будет соответствующим образом выбросить ошибку 404, если пользователь не существует, и он побросит 500 с ошибками проверки, если по какой-то причине обновление завершится неудачей.

Читайте о кодах состояния HTTP и как они могут помочь вам here

Смежные вопросы