0

사용자가 번호를 입력하고 양식을 아약스와 함께 제출하는 레일 앱에 양식이 있습니다. 모든 매개 변수가있는 경우 내 게임 컨트롤러에 새 게임이 만들어집니다. 두 개의 hidden_field_tags 매개 변수를 매우 잘 컨트롤러에 전달하지만 가장 중요한 매개 변수, 사용자 입력에서 얻은 매개 변수가 컨트롤러로 전달하지 않는 것 같습니다.레일 원격 양식 매개 변수가 컨트롤러로 전달되지 않음

내 양식 :

<%= form_for @game, :url => {:controller => "games", :action => "create" }, :html => { :role => 'form' }, remote: true, method: :post do |f| %> 
    <div class="row"> 
    <div class="col-md-4 col-md-offset-4"> 
     <div class="input-group"> 
     <%= f.text_field :user_stake, class: 'form-control' %> 
     <span class="input-group-btn"> 
      <%= f.submit 'Go', :html => { :type => "button" }, class: "btn btn-default" %> 
     </span> 
     </div> 
    </div> 
    </div> 

    <%= hidden_field_tag 'user_id', current_user.id %> 
    <%= hidden_field_tag 'jackpot_id', @jackpot.id %> 

<% end %> 

컨트롤러 :

before_action :game_params, only: [:create] 

    def create 
    @game = Game.new(game_params) 
    if @game.save 
     @jackpot = Jackpot.find(params[:jackpot_id]) 
     ActionCable.server.broadcast 'jackpot_channel', 
             users: Jackpot.where(id: @jackpot.id), 
             pot: @jackpot, 
             user: User.find(@game.user_id), 
             game: @game, 
             stake: @game.user_stake.to_s 
    else 
     ActionCable.server.broadcast 'jackpot_channel', 
             error: @game.errors.full_messages 
    end 
    end 

    def new 
    @game = Game.new 
    end 

    private 
    def game_params 
     params.permit(:user_stake, :user_id, :jackpot_id) 
    end 

무엇 @game에 입력하는 것은 내 마이그레이션에서 기본값으로 설정 한 0.0 user_stake로 저장되지됩니다 상관없이 . 내가 여기서 뭘 잘못하고 있는지 전혀 모르겠다. 어떤 아이디어? 감사!

+0

지금 양식을 제출할 때 레일 서버에 힌트가 있습니까? –

+0

'before_action : game_params, only : [: create]'를 제거하십시오. 그것은 낭비하는 시간/기억을 제외하고는 절대적으로 아무것도하지 않습니다. – max

+0

DB 열 유형이란 무엇입니까? – max

답변

2

당신은 제대로 입력을 중첩하지 않는 :

{ 
    game: { 
    user_stake: 1.2 
    }, 
    user_id: 3, 
    jackpot_id: 4 
} 
:

<%= form_for @game, html: { role: 'form' }, remote: true %> 
    <%= f.text_field :user_stake, class: 'form-control' %> 
    <%= hidden_field_tag 'user_id', current_user.id %> 
    <%= hidden_field_tag 'jackpot_id', @jackpot.id %> 
    # .. 
<% end %> 

이것은 PARAMS 다음 해시를 줄 것이다 액세스하기 위해, 나는 게임을 요구하는 game_params을 변경 권 해드립니다

허용 목록을 통해 전송하는 경우 :

{ 
    user_id: 3, 
    jackpot_id: 4 
} 

<%= form_for @game, html: { role: 'form' }, remote: true %> 
    <%= f.text_field :user_stake, class: 'form-control' %> 
    <%= f.hidden_field_tag 'user_id', current_user.id %> 
    <%= f.hidden_field_tag 'jackpot_id', @jackpot.id %> 
    # .. 
<% end %> 

그리고 적절하게 허용 된 사이트 목록 : - NEVER가 PARAMS을 통해 현재 사용자 ID를 전달

private 
    def game_params 
    params.require(:game) 
      .permit(:user_stake, :user_id, :jackpot_id) 
    end 

을하지만, 여기에 거대한 경고 플래그가 솔루션에

는 단순히 중첩 입력입니다 악의적 인 사용자가 웹 검사기만으로 해킹하는 것은 정말 쉽습니다. 대신 세션에서 직접 값을 사용하십시오.

사용자 암호 나 응용 프로그램 비밀을 알고있는 경우를 제외하고는 위조 할 수 없습니다.

또한 게임이 잭팟에 속한 경우 nested resource으로 설정하고 경로에 ID를 넣으면 부모 리소스에 자식을 추가한다는 것을 명확하게 보여주는 RESTful 구조가 생성되므로 - 숨기는 대신 요청 본문에 중요한 정보. 필요한 숨겨진 입력이없는 방법


class GamesController 
    before_action :set_jackpot, only: [:new, :create, :index] 

    # GET /jackpots/:jackpot_id/games/new 
    def new 
    @game = @jackpot.games.new 
    end 

    # POST /jackpots/:jackpot_id/games 
    def create 
    @game = @jackpot.games.new(game_params) do |g| 
     g.user = current_user 
    end 

    if @game.save 
     # ... 
    else 
     # ... 
    end 
    end 

    # GET /jackpots/:jackpot_id/games 
    def index 
    @games = @jackpot.games 
    end 

    private 

    def set_jackpot 
     @jackpot = Jackpot.includes(:games) 
         .find(params[:jackpot_id]) 
    end 

    def game_params 
     params.require(:game).permit(:user_stake) 
    end 
end 

<%= form_for [@jackpot, @game], remote: true, html: { role: 'Form' } do |f| %> 
    <div class="row"> 
    <div class="col-md-4 col-md-offset-4"> 
     <div class="input-group"> 
     <%= f.number_field :user_stake, class: 'form-control' %> 
     <span class="input-group-btn"> 
      <%= f.submit 'Go', :html => { :type => "button" }, class: "btn btn-default" %> 
     </span> 
     </div> 
    </div> 
    </div> 
<% end %> 

# routes.rb 
resources :jackpots do 
    resources :games, shallow: true 
end 

.

+0

감사합니다. 매우 포괄적이며 유용한 답변입니다. 나는 네가 제안한 것을했고 모든 것이 완벽하게 작동하고있는 것처럼 보인다. 한 가지 질문 : 저는 게임이 잭팟에 속해 있지 않기 때문에 당신이 말한 것과 같은 경로를 유지해야하는지 궁금합니다. 오히려 나는 많은 사람들에게 has_many : jackpots, through => 게임이있는 many to many association을 설정했습니다. 당신이 말한 것과 같이 길을 유지해야합니까? 감사합니다 – RT5754

+0

잘 경우에 당신은 대성공과 게임 사이 belongs_to 협회가있다. – max

+0

좋아, 할께 고마워. – RT5754

2

서버 로그를 검사하여 컨트롤러의 create 메소드에 게시되는 것을 확인할 수 있습니다. 게임 파라미터가 game 해시로 캡슐화되어있는 것 같습니다.

def game_params 
    params.require(:game).permit(:user_stake, :user_id, :jackpot_id) 
end 
+0

답변 해 주셔서 감사합니다. 양식 제출시 로그에 다음과 같이 표시됩니다. INSERT INTO "games"("user_id", "jackpot_id", "created_at", "updated_at"). user_stake가 없습니다. 그냥 분명히 게임이 아닌 user_stake를 전달하려고합니다. 게임은 내 모델입니다 – RT5754

+0

예 ... 게임 매개 변수가 매개 변수를 필터링 할 수 있습니다. 'game_params'와'params'의 결과를 검사 할 것을 권합니다. 이렇게하면 데이터가 필터링되는 위치를 진단하는 데 도움이됩니다. 'byebug '(http://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-byebug-gem)를'create' 메소드 맨 위에두면이 변수들을 검사하는 데 도움이 될 것입니다. –