Добавить запись в существующую коллекцию в приложении Rails - PullRequest
0 голосов
/ 06 декабря 2018

Я пытаюсь разработать модель, в которой пользователь может добавить просматриваемый рецепт в существующее меню созданных им рецептов, аналогично добавлению песни в пользовательский список воспроизведения.Я полагаю, что правильно настроил модели (используя отношения «многие ко многим»), однако я не уверен, как добавить фактические записи в выбранную коллекцию.Любое руководство будет полезно.Мой код, как показано ниже.

Контроллер меню

class MenusController < ApplicationController
before_action :set_search

def show
    @menu = Menu.find(params[:id])
end

def new
    @menu = Menu.new
end

def edit
    @menu = Menu.find(params[:id])
end

def create
    @menu = current_user.menus.new(menu_params)

    if @menu.save
        redirect_to @menu
    else
        render 'new'
    end
end

def update
    @menu = Menu.find(params[:id])

    if @menu.update(menu_params)
        redirect_to @menu
    else
        render 'edit'
    end
end

def destroy
    @menu = Menu.find(params[:id])
    @menu.destroy

    redirect_to recipes_path
end

private
def menu_params
    params.require(:menu).permit(:title)
end
end

Модель меню

class Menu < ApplicationRecord
belongs_to :user
has_many :menu_recipes
has_many :recipes, through: :menu_recipes
end

menu_recipe Модель

class MenuRecipe < ApplicationRecord
  belongs_to :menu
  belongs_to :recipe
end

Модель рецепта

class Recipe < ApplicationRecord
belongs_to :user
has_one_attached :cover

has_many :menu_recipes
has_many :menus, through: :menu_recipes


end

Модель пользователя

class User < ApplicationRecord
has_secure_password
has_one_attached :profile_image
has_many :recipes
has_many :menus
end

Ответы [ 2 ]

0 голосов
/ 06 декабря 2018

Вы можете сделать что-то вроде:

def add_recipe_to_menu
 menu = current_user.menus.find params[:id]
 recipe = current_user.recipes.find params[:recipe_id]

 menu.recipes << recipe
end

Это добавит рецепт просмотра к существующему меню рецептов.

0 голосов
/ 06 декабря 2018

Сначала убедитесь, что вы создали новую запись для пользователя:

class MenusController < ApplicationController
  # make sure you authenticate the user first
  before_action :authenticate_user!, except: [:show, :index]

  def new 
    @menu = current_user.menus.new
  end

  def create
    @menu = current_user.menus.new(menu_attributes)
    # ...
  end
end

Затем мы можем просто добавить выбор в форму, где пользователь может выбирать из своих рецептов:

# use form_with in Rails 5.1+
<%= form_for(@menu) do |f| %>
  ... other fields
  <div class="field">
    <%= f.label :recipe_ids %>
    <%= f.collection_select :recipe_ids, f.object.user.recipies, :id, :name, multiple: true %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

f.object обращается к экземпляру модели, заключенному в построитель форм.

recipe_ids - это специальный метод установки / получения, созданный ActiveRecord для ассоциаций has_many.Как вы можете догадаться, он возвращает массив идентификаторов и позволяет установить связь с массивом идентификаторов - автоматически вставляя / удаляя строки в таблице соединений в процессе.

Затем вам просто нужно внести в белый список параметр recipe_ids:

def menu_attributes
  params.require(:menu)
        .permit(:foo, :bar, recipe_ids: [])
end

recipe_ids: [] в белый список разрешенных скалярных типов.Поскольку это опция хеширования, она должна быть указана после любых позиционных аргументов, чтобы быть синтаксически допустимой.

rb(main):003:0> params.require(:menu).permit(:foo, recipe_ids: [], :bar)
SyntaxError: (irb):3: syntax error, unexpected ')', expecting =>
...