所以我的问题或多或少如下。我有一个带有以下类的rails应用程序:
每个用户都可以拥有多种技能,并且可以从用户配置文件屏幕添加这些技能,这是用户控制器的显示操作。目前我已经设置了技能并且能够创建,但我无法在用户配置文件中添加预先构建的技能,我不确定是否需要在Users控制器中添加新操作或者我只需要使用来自技能控制器的更新操作。我的理想解决方案是管理员用户(已经创建并整理出来)继续用户配置文件并添加技能,但我完全不知道如何实现这一点。我的控制器,模型等如下:
skills_controller.rb
class SkillsController < ApplicationController
before_action :set_skill, only: [:show, :edit, :update, :destroy]
# GET /skills
# GET /skills.json
def index
@skills = Skill.all
end
# GET /skills/1
# GET /skills/1.json
def show
end
# GET /skills/new
def new
@skill = Skill.new
end
# GET /skills/1/edit
def edit
end
# POST /skills
# POST /skills.json
def create
@skill = Skill.new(skill_params)
user = User.find(params[:user_id])
respond_to do |format|
if @skill.save
format.html { redirect_to @skill, notice: 'Skill was successfully created.' }
format.json { render :show, status: :created, location: @skill }
else
format.html { render :new }
format.json { render json: @skill.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /skills/1
# PATCH/PUT /skills/1.json
def update
respond_to do |format|
if @skill.update(skill_params)
format.html { redirect_to @skill, notice: 'Skill was successfully updated.' }
format.json { render :show, status: :ok, location: @skill }
else
format.html { render :edit }
format.json { render json: @skill.errors, status: :unprocessable_entity }
end
end
end
# DELETE /skills/1
# DELETE /skills/1.json
def destroy
@skill.destroy
respond_to do |format|
format.html { redirect_to skills_url, notice: 'Skill was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_skill
@skill = Skill.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def skill_params
params.require(:skill).permit(:name, :badge_url, :user_id)
end
end
users_controller.rb
class UsersController < ApplicationController
before_action :logged_in_user, only: [:index, :edit, :update]
before_action :correct_user, only: [:edit, :update]
def new
@user = User.new
@group_options = Group.all.map{|g| [ g.name, g.id] }
@subunit_options = Subunit.all.map{|s| [ s.name, s.id] }
end
def index
@users = User.paginate(page: params[:page]).order('created_at ASC')
end
def chf_index
@chf = User.where(group_id: 1).paginate(page: params[:page]).order('created_at ASC')
end
def rmc_index
@rmc = User.where(group_id: 2).paginate(page: params[:page]).order('created_at ASC')
end
def ra_index
@ra = User.where(group_id: 3).paginate(page: params[:page]).order('created_at ASC')
end
def show
@user = User.find(params[:id])
@user_training_events = User.find(params[:id]).training_events.to_a
@event_id = TrainingEvent.where(user_ids: @user.id).all
@group = Group.find(@user.group_id)
if @user.subunit_id.nil?
else
@subunit = Subunit.find(@user.subunit_id)
end
@current_user_id = current_user.id
if @user.rank_id.nil?
else
@rank = Rank.find(@user.rank_id)
end
end
def create
@user = User.new(user_params)
if @user.save
@user.send_activation_email
flash[:info] = "Please check your email to activate your account."
redirect_to root_url
else
render 'new'
end
end
def edit
@user = User.find(params[:id])
@subunit_options = Subunit.all.map{|s| [ s.name, s.id] }
@group_options = Group.all.map{|g| [ g.name, g.id] }
end
def update
@user = User.find(params[:id])
@subunit_options = Subunit.all.map{|s| [ s.name, s.id] }
if @user.update(user_params)
flash[:success] = "Profile updated"
redirect_to @user
else
render 'edit'
end
end
private
# Decides which parameters can be passed to user creation
def user_params
params.require(:user).permit(:username, :email, :group_id, :subunit_id, :rank_id, :training_event_id, :password, :password_confirmation)
end
# Confirms a logged-in user.
def logged_in_user
unless logged_in?
store_location
flash[:danger] = "Please log in."
redirect_to login_url
end
end
# Confirms the correct user.
def correct_user
@user = User.find(params[:id])
redirect_to(root_url) unless current_user?(@user) || current_user.admin?
end
end
skill.rb
class Skill < ActiveRecord::Base
belongs_to :user
end
user.rb
class User < ActiveRecord::Base
attr_accessor :remember_token, :activation_token, :reset_token
before_save :downcase_email
before_create :create_activation_digest
belongs_to :group
has_many :ranks
has_many :skills
has_many :mission_notes
has_and_belongs_to_many :training_events
accepts_nested_attributes_for :skills
validates :username, presence: true
validates :email, presence: true
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
validates :group_id, presence: true
has_secure_password
validates :password, length: { minimum: 6 }, allow_blank: true
# Returns the hash digest of the given string.
def User.digest(string)
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
BCrypt::Engine.cost
BCrypt::Password.create(string, cost: cost)
end
# Returns a random token.
def User.new_token
SecureRandom.urlsafe_base64
end
# Remembers a user in the database for use in persistent sessions.
def remember
self.remember_token = User.new_token
update_attribute(:remember_digest, User.digest(remember_token))
end
# Returns true if the given token matches the digest.
def authenticated?(remember_token)
return false if remember_digest.nil?
BCrypt::Password.new(remember_digest).is_password?(remember_token)
end
# Forgets a user.
def forget
update_attribute(:remember_digest, nil)
end
# Converts email to all lower-case.
def downcase_email
self.email = email.downcase
end
# Creates and assigns the activation token and digest.
def create_activation_digest
self.activation_token = User.new_token
self.activation_digest = User.digest(activation_token)
end
# Returns true if the given token matches the digest.
def authenticated?(attribute, token)
digest = send("#{attribute}_digest")
return false if digest.nil?
BCrypt::Password.new(digest).is_password?(token)
end
# Activates an account.
def activate
update_attribute(:activated, true)
update_attribute(:activated_at, Time.zone.now)
end
# Sends activation email.
def send_activation_email
UserMailer.account_activation(self).deliver
end
# Sets the password reset attributes.
def create_reset_digest
self.reset_token = User.new_token
update_attribute(:reset_digest, User.digest(reset_token))
update_attribute(:reset_sent_at, Time.zone.now)
end
# Sends password reset email.
def send_password_reset_email
UserMailer.password_reset(self).deliver
end
def password_reset_expired?
reset_sent_at < 2.hours.ago
end
end
最后是routes.rb
Rails.application.routes.draw do
resources :skills
resources :subunits
resources :mission_notes
resources :training_events
get 'password_resets/new'
get 'password_resets/edit'
root "categories#index"
get 'static_pages/home'
get 'help' => 'static_pages#help'
get 'signup' => 'users#new'
get 'login' => 'sessions#new'
post 'login' => 'sessions#create'
delete 'logout' => 'sessions#destroy'
get 'dynamic' => 'subunits#dynamic'
get 'chf_index' => 'users#chf_index'
get 'rmc_index' => 'users#rmc_index'
get 'ra_index' => 'users#ra_index'
resources :categories, :has_many => :notes
resources :notes
resources :users do
resources :skills
end
resources :ranks
resources :groups
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
end
如果您需要其他信息,请告诉我
修改 添加以下作为我的函数定义
def add_skill_to_user
user = User.find(params[:id])
user.skills.create(skill_params) #skill name, level...
@skills_options = Skill.all.map{|s| [ s.name, s.id] }
#whatever happens when this is is done, redirect, json answer etc...
if user.skills.update_all(skill_params)
flash[:success] = "Skill Added"
else
render 'add_skill_to_user'
end
end
private
# Set skills params whitelist
def skill_params
params.permit(:name, :user_id)
end
以及以下路线
post 'users/:id/add_skill_to_user' => 'users#add_skill_to_user'
这是我的表格
<%= form_tag({controller: "users", action: "add_skill_to_user"}, method: "put") do %>
<%= collection_select(:skill, :name, Skill.all, :id, :name) %>
<%= submit_tag 'Submit' %>
<%end%>
我现在无法提交带有技能名称和技能ID的表单,因为我收到此错误Empty list of attributes to change
答案 0 :(得分:0)
您想要创建一个搜索用户的方法,然后添加技能。
def add_skill_to_user
user = User.find(params[:user_id])
user.skills.create(skill_params) #skill name, level...
#whatever happens when this is is done, redirect, json answer etc...
end
然后创建路由,接受视图中的表单发送用户名和技能信息。
这应该足够了。
编辑:
根据表格:
http://guides.rubyonrails.org/form_helpers.html
form_tag({controller: "admin", action: "set_user_skill"}, method: "post(or put)") Then the form... and the submit button.