Как каждый пользователь может последовательно сделать выбор

#ruby-on-rails

Вопрос:

У меня есть приложение Fantasy Soccer Rails, и я пытаюсь добавить функцию, которая заключается в том, чтобы каждый пользователь делал выбор проекта, по одному пользователю за раз, один за другим; как я могу это сделать? Пользователь создает строку, относящуюся к каждому выбранному игроку, чтобы сохранить его в своей личной команде. Вот часть кода, который, как я думаю, касается этой функции, но требуется больше, пожалуйста, скажите мне. Спасибо

пользователь.rb

 class User lt; ApplicationRecord  # Include default devise modules. Others available are:  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable  devise :database_authenticatable, :registerable,  :recoverable, :rememberable, :validatable   has_one :squad end  

users_controller.rb

 class UsersController lt; ApplicationController  def update  skip_authorization  @user = current_user  @user.update(user_params)  redirect_to profile_path  end   def user_params  params.require(:user).permit(:first_name, :last_name, :mobile, :drft_pass, :drft_shortlist)  end   has_one :squad end  

line_item.rb

 class LineItem lt; ApplicationRecord  belongs_to :player  belongs_to :squad end  

line_items_controller.rb

 class LineItemsController lt; ApplicationController before_action :set_line_item, only: [:destroy] before_action :set_player, only: [:create]     def create  #@player_id = @player  #chosen_player = @player  #@squad_id = @squad  #current_squad = @current_squad      if LineItem.where(squad_id: params[:squad_id]).where(player_id: params[:player_id]).count gt; 0   message = 'This player is already on your Squad'    elsif    LineItem.where(player_id: params[:player_id]).present?   message = 'This player is already selected by other Coach'    else   @line_item = LineItem.new  @player = Player.find(params[:player_id])  @squad = Squad.find(params[:squad_id])  @line_item.squad = @squad  @line_item.player = @player  @line_item.save  message = 'Success. The player was added to your Squad'       end  redirect_to players_path  flash[:notice] = message  end   def destroy   @line_item.destroy  redirect_to user_squad_path(current_user.id, :squad_id)  end   private   def line_item_params  params.require(:line_item).permit(:player_id, :squad_id)  end   def set_line_item  @line_item = LineItem.find(params[:id])  end   def set_player  @player = Player.find(params[:player_id])  end     end  

player.rb

 class Player lt; ApplicationRecord  include PgSearch::Model  pg_search_scope :search_by_full_name, against: [:name, :club, :pos] end  

players_controller.rb

 class PlayersController lt; ApplicationController  #before_action :set_players, only: [:show, :edit, :update, :destroy]    def index  if params[:term]  @players = Player.search_by_full_name(params[:term]).paginate(page: params[:page], per_page: 20)  else  @players = Player.paginate(page: params[:page], per_page: 20)  end  end   def show  @player = Player.find(params[:id])    end   private   def player_params  params.require(:player).permit()  end   def set_player  @player = Player.find(params[:id])  end end  

squad.rb

 class Squad lt; ApplicationRecord  has_one_attached :photo   belongs_to :user   has_many :line_items, dependent: :destroy  has_many :players, through: :line_items    validates :name, presence: true  end  

squads_controller.rb

 class SquadsController lt; ApplicationController  before_action :authenticate_user!  #before_action :set_squad   def show    end   def new  @user = User.find(params[:user_id])  @squad = Squad.new  end   def create  @user = User.find(params[:user_id])  @squad = Squad.new(squad_params)  @squad.user = @user  if @squad.save  redirect_to user_squad_path(current_user.id, @squad)  flash[:notice] = 'Success. Your squad was created'  else  render "new"  flash[:notice] = 'Squad not created; please try again'  end  end   def edit  @user = User.find(params[:user_id])  @squad = Squad.find(params[:squad_id])  end   def update  @user = User.find(params[:user_id])  @squad = Squad.find(params[:id])  @squad.update(squad_params)  redirect_to user_squad_path(current_user.id, @squad)  end      def destroy  @squad = Squad.find(params[:squad_id])   @squad.destroy  redirect_to root_path  end   private   def set_squad  @squad = @current_squad  end    def squad_params  params.require(:squad).permit(:name, :sigla, :photo)  end  end  

Ответ №1:

Итак, здесь многое происходит — слишком многое, чтобы мы могли помочь в одном вопросе. Говоря «Это не работает, пожалуйста, исправьте это», вы не получите полезных ответов. Что именно не работает? Как это не работает? И в чем именно вам нужна помощь?

Однако несколько простых советов для начала. Во-первых, вы могли бы намного лучше использовать встроенные помощники Rails. Например, в вашем line_items_controller , попробуйте что-то вроде этого:

 def create  line_item = LineItem.find_by(player_id: line_item_params[:player_id])  if line_item.present?  message = if line_item.squad_id == current_user.squad_id  'This player is already on your Squad'  else  'This player is already selected by other Coach'  end  else  @line_item = LineItem.new  @line_item.squad = current_user.squad  @line_item.player = Player.find(line_item_params[:player_id])  message = if @line_item.save  'Success. The player was added to your Squad'  else  "Error - couldn't save your selection"  end  end  flash[:notice] = message  redirect_to players_path end  

Обратите внимание, что при использовании current_user.squad будет возвращена связанная запись, а squad.line_items вернет связанные записи. Это означает, что (а) вам не нужно писать запросы и (б) вы всегда будете защищать себя от случайного предоставления пользователю доступа к записям, к которым у них не должно быть доступа (например, к командам других людей).

Я также изменил логику вашего if блока, чтобы уменьшить количество запросов к базе данных. Во-первых, найдите строку, содержащую этого игрока (используя find_by , а не where потому, что, предположительно, должна быть только одна такая запись, потому что Игрок должен быть только в одной команде). Если есть какие-либо записи, проверьте, совпадает ли состав для этого элемента строки с составом текущего пользователя, и измените сообщение в зависимости от этого.

Затем назначьте игрока в команду пользователя, если они доступны, почти так же, как вы делали раньше. Вы не используете строгие параметры, даже если вы определили необходимый метод, например, в line_items_controller. Вы заметите, что я вставил эту ссылку в приведенный выше пример. Большое изменение в этом блоке заключается в том, что лучше избегать использования squad параметра, потому что (предположительно) каждый пользователь может создавать элементы строк только для своего отряда! Так что я поменял это на current_user.squad .

И обратите внимание, что вам нужно настроить флэш — сообщение перед перенаправлением-это фактически конец вашего метода.

Это дает вам один (!) из ваших методов, очищенных и, надеюсь, делающих то, что вы хотите. Но в целом, как я уже сказал, вам, вероятно, придется рассказать нам, в чем именно заключается ваша проблема.

Комментарии:

1. Спасибо за помощь… Я знал, что код не очень СУХОЙ, но он все еще находится на ранней стадии, я планирую провести некоторую очистку и наверняка воспользуюсь вашими идеями… Но все работает нормально, моя представленная проблема была больше связана с добавлением того, что следующая функция каждого пользователя делает выбор черновика, каждый раз по одному, но не знает, с чего начать

2. Речь идет не столько о сухости, сколько об эффективном использовании помощников Rails. И я думаю, что вам нужно гораздо яснее представлять свою реальную проблему — из вопроса следует, что код не работает, а не то, что вы хотите получить совет о том, как добавить новую функцию (и даже зная это, совсем не ясно, в чем ваша реальная проблема!).

3. ОК… Я переработаю вопрос и постараюсь немного прояснить, что мне нужно, спасибо… Как я уже сказал, все работает нормально, просто хочу добавить эту новую функцию

4. Звучит хорошо. Ключом будет: (1) то, что происходит сейчас; (2) что вы хотите изменить; и (3) какие ключевые биты кода задействованы. В идеале также то, что вы уже пробовали и что именно идет не так.