为具有预定义数据的用户创建关联

时间:2017-03-14 14:29:02

标签: ruby-on-rails activerecord

嘿,任何帮助都会受到赞赏!

基本上我有两个模型 - 用户(使用Devise)和Sport

class User < ApplicationRecord
  has_and_belongs_to_many :sports
end

class Sport < ApplicationRecord
  has_and_belongs_to_many :users
end

我有一个预定义的运动列表,这些运动会被播种到我的数据库中(例如跑步,举重等)。我想要做的是拥有用户登录,然后选择他们做的运动,并通过关联保存。然后,这允许用户搜索并查看其他用户做的运动等。

我设法通过控制台创建关联,如下所示:

user = User.find(1)
sport = Sport.find(1)
user.sports << sport

但我无法想象如何将其翻译成表格。

到目前为止,我已经得到了它,尽管它所做的只是创造一个新的运动(我不想要):

#sports_controller.rb
def index
  @sports = Sport.where(["name ILIKE ?", "%#{params[:search]}%"])
end

def new
  @sport = Sports.new
end

def create
  @sport = current_user.sports.create(sports_params)
end

private
 def sports_params
 params.require(:sport).permit(:name)
end

然后是我的表格:

#sports/new.html.erb
<%= form_for @sport do |f| %>
  <div class="form-group">
    <%= f.label :exercises %><br>
    <%= f.collection_check_boxes :name, Sport.all, :id, :name %>
  </div>

  <%= f.button :submit %>
<% end %>

通过这个控制器做对吗?我真的迷失了如何做到这一点,这是我的uni项目的核心功能。

提前致谢!

1 个答案:

答案 0 :(得分:1)

首先,我会摆脱你的SportsController,这感觉你只是在更新一个用户。 SportsController将用于自己创建运动,在播种时你不需要这样做。

因此,如果您还没有,请添加用户路线(这不允许更新设计字段,例如密码,但这超出了此问题的范围):

resources :users

然后在ApplicationController中添加以下方法:

def after_sign_in_path_for(_resource)
  edit_user_path(current_user)
end

这将在登录其编辑页面后重定向用户。

最后形式:

#users/edit.html.erb

<%= form_for @user do |form| %>

  <% @sports.each do |sport| %>
    <%= check_box_tag "user[sport_ids][]", sport.id, form.object.sports.include?(sport) %>
    <%= sport.name %>
  <% end %>

  <%= f.button :submit %>
<% end %>

这将传递一系列sport_ids,由于Rails魔术:),它会自动将所有选定的运动与您的用户相关联。神奇的是你也可以像这样关联对象:

@model.associated_model_ids << [1,2,3]

您的UsersController:

def UsersController < ApplicationController
  def edit
    @user = User.find(params[:id])
    @sports = Sport.all.order(name: :asc)
  end

  def update
    @user = User.find(params[:id])

    if @user.update(user_params)
      redirect_to @user
    else
      render 'edit'
    end
  end 

  def show
    @user = User.find(params[:id])    
  end  

  private

  def user_params
    params.require(:user).permit(sport_ids: [])
  end
end

您需要添加用户show.html.erb模板,但这应该足以让您前进。我认为有一个更好的方法来做复选框,所以我可能稍后更新,但这应该工作。

查看它是否有效的示例:

#users/show.html.erb

<%= @users.sports.map(&:name).join(', ') %>