Rails - ассоциация один к одному - PullRequest
0 голосов
/ 10 мая 2019

Давайте предположим, что у меня есть список моментов и список маршрутизаторов.У памятника есть один маршрутизатор, а маршрутизатор принадлежит памятнику.Это отношения один на один.Обычно это делается для того, чтобы в таблице маршрутизатора был внешний ключ (памятник_идентификатора).Это довольно просто, мне просто нужен выбор со списком памятников, и связь для этого маршрутизатора установлена.

Но теперь давайте предположим, что я хочу сделать эти ассоциации на стороне памятника.Например, у меня будет _form для памятника, а внутри этой формы у меня есть выбор доступных маршрутизаторов.Как я могу этого достичь?Потому что я знаю, что это вызовет ошибку, потому что у меня нет атрибута на стороне памятника для сохранения выбранного маршрутизатора.

Это вообще возможно, что я пытаюсь сделать?И если да, не могли бы вы привести пример?Спасибо!

Прошу прощения за английский.

Ответы [ 3 ]

0 голосов
/ 10 мая 2019

То, что вы описываете, - это стандарт болота has_one / belongs_to.

Обе модели, содержащие has_one или belongs_to, обе способны управлятьотношения, и у обоих есть средства доступа для обновления ассоциации.

Предполагая, что у вас есть это ...

class Monument
  belongs_to :router
end

class Router
  has_one :monument
end

Тогда оба из них будут работать точно так, как вы ожидаете, что они:

router.monument = <some monument>

или

monument.router = <some router>
0 голосов
/ 13 мая 2019

В итоге я решил свою проблему с помощью набора ответов, поэтому спасибо за вашу помощь.

Я думал, что, если я добавлю router_id в monument_params, рельсы выберут параметр сто же имя и создаст ассоциацию самостоятельно, но, похоже, что Rails нужен объект, а не идентификатор.Так что это было мое решение:

  • В моей форме памятника у меня есть выбор, чтобы выбрать Маршрутизатор
<%= f.select :router_id, Router.all.collect { |s| [s.mac_address, s.id]}, {}, {class:"routerSelect", include_blank: true}  %>
  • Затем в моем monuments_controller всоздать и обновить метод я делаю так:
def create
   @monument = Monument.new(monument_params)
   @monument.router = Router.find(params[:monument][:router_id])
   if @monument.save
   ...
end

def update
   if @monument.update(monument_params)
      @monument.router = Router.find(params[:monument][:router_id])
   ...
end

Это не лучшее решение, но оно решает мою проблему.Спасибо

0 голосов
/ 10 мая 2019

Как-то так должно работать.

def create
  monument = Monument.new(monument_params)
  if monument.save
    if router.present?
      router.monument = monument
      if router.save
        render json: monument, status: :ok
      else
        render json: router.errors, status: :unprocessable_entity 
      end
    else
      render json: monument, status: :ok
    end
  else
    render json: monument.errors, status: :unprocessable_entity 
  end
end

def permitted_params
  params.require(:monument).permit(:name,...,:router_id)
end

def monument_params
  permitted_params.except(:router_id)
end

def router_id
  permitted_params[:router_id]
end

def router
  if router_id
    Router.find router_id
  end
end

Возможно, вам придется изменить, если ваши параметры выглядят так

params.require(:monument).permit(:name, {router_attributes: [:id]})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...