2013-09-03 3 views
0

Я только начал изучать Ruby и Ruby on Rails, и на самом деле это первый раз, когда я действительно должен задать вопрос о SO, и это действительно сходит с ума.Модель пуста из-за несущей волны - nested_attributes

Я программирую REST api, где мне нужно получить URL-адрес изображения и сохранить его в моем db.

Для этого, я сделал модель под названием ImageSet, который использует carrierwave для хранения загруженных изображений, как это:

class ImageSet < ActiveRecord::Base 
    has_one :template 

    mount_uploader :icon1, Icon1Uploader 
    mount_uploader :icon2, Icon2Uploader 

    def icon1=(url) 
    super(url) 
    self.remote_icon1_url = url 
    end 

    def icon2=(url) 
    super(url) 
    self.remote_icon2_url = url 
    end 
end 

Это icon1 и icon2 оба получили в качестве URL-адресов, следовательно, сеттер переопределение, и они не может быть нулевым. Мои классы-загрузчики создают несколько версий с белым списком расширений и переопределением полного_файла.

Тогда у меня есть этот класс шаблонов, который получает вложенные атрибуты для ImageSet.

class Template < ActiveRecord::Base 
    belongs_to :image_set 

    accepts_nested_attributes_for :image_set 

    (other stuff) 

    def image_set 
    super || build_image_set 
    end 
end 

Эта модель имеет image_set_id, которая не может быть нулевой.

Учитывая простой запрос, как пост с JSON:

{ 
    "template": 
     { 
     "image_set_attributes": 
     { 
     "icon1": "http....", 
     "icon2": "http...." 
     } 
     } 
    } 

Это дает всегда: ImageSet не может быть пустым.

я могу получить доступ к temp.image_set из консоли, если temp является Template, и я могу установить значение там тоже, как, temp.image_set.icon = 'http...', но я не могу показаться, чтобы выяснить, почему это нарушение там. Необходимо создать image_set, установить его атрибуты, которые сохранить его для шаблонного класса, который бы присвоить его идентификатор в соответствующий столбец в своем модельно

Моего контроллер делает:

(...) 
def create 
@template = Template.create(params) 
if @template 
    render status: 200 
else 
    render status: 422 
end 
end 

private 

def params 
params.require(:template).permit(image_set_attributes: [:id, :icon1, :icon2]) 
end 
(...) 

Надеется, что вы может дать мне совет по этому.

Спасибо!

+0

Насколько я могу видеть, вы разрешаете параметры, включая: id, но вы не отправляете его с запросом json, может ли это дать вам пустые параметры hash и => пустой экземпляр ImageSet? – okliv

+0

@ okliv, это было бы правильно, если бы разрешение остановило атрибуты от создания в результате ошибки «нет». Но это не так, поскольку это разрешено, оно позволяет передавать его, когда присутствует на хеше, но как только вы его сохраните, он будет изменен на его реальное значение из db. Так почему же он там? Потому что, поскольку он CRUD, я хочу разрешить его для обновлений, которые необходимы для идентификации модели для изменения. Спасибо за ваш комментарий. –

ответ

0
  1. accepts_nested_attributes не работает должным образом с использованием owner_to.

    Это может быть обманут работать в определенных обстоятельствах, но вы лучше меняя свое приложение в другом месте, чтобы сделать что-то «рельсы путь.»

  2. шаблоны validate_presence_of :image_set, справа? Если это так, проблема в том, что это означает, что ImageSets всегда должен быть создан до их шаблонов, но accepts_nested_attributes считает, что шаблон является родительским и пытается сначала сохранить родителя.

    Простейшая вещь, которую вы можете сделать, это переключить отношения, поэтому шаблон has_one :image_set и ImageSet belongs_to :template. В противном случае вам придется написать некоторую довольно нечетную логику контроллера, чтобы иметь дело с параметрами, как ожидалось.

+0

не всегда - http://stackoverflow.com/questions/1313149/getting-fields-for-and-accepts-nested-attributes-for-to-work-with-a-belongs-to-r/2441463#2441463 - см. самый популярный ответ – okliv

+0

См. выше: Я попытался уточнить дальше. – Taavo

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