【问题标题】:Add Record to Existing Collection in a Rails App将记录添加到 Rails 应用程序中的现有集合
【发布时间】:2018-12-06 02:16:40
【问题描述】:

我正在尝试开发一种模型,在该模型中,用户可以将他们正在查看的食谱添加到他们创建的现有食谱菜单中,类似于将歌曲添加到自定义播放列表中。我相信我已经正确设置了模型(使用多对多通过关系)但是我不确定如何将实际记录添加到选定的集合中。任何指导都会有所帮助。我的代码如下。

菜单控制器

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

【问题讨论】:

    标签: ruby-on-rails ruby model controller associations


    【解决方案1】:

    你可以这样做:

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

    它将在现有的食谱菜单中添加一个查看食谱。

    【讨论】:

      【解决方案2】:

      首先确保您从用户身上建立新记录:

      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 关联创建的特殊 setter/getter。正如您可能已经猜到的那样,它返回一个 id 数组并让关联设置为一个 id 数组——在此过程中自动插入/删除连接表中的行。

      然后您只需将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 =>
      

      【讨论】:

      • 我喜欢你这样做的方式,但我遇到了两个问题:1)我希望用户能够在表单中选择多个食谱以添加到每个菜单 2)什么变量我应该在视图中调用以显示配方信息吗?调用 recipe.title 会引发错误,提示“recipe”无法识别。
      • 1.) 将multiple: true 选项添加到collection_select。 2)。关联是 has_many,因此您必须访问 recipes 并遍历结果。不过,这确实是一个单独的问题。
      猜你喜欢
      • 2018-05-18
      • 2020-06-22
      • 2018-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多