RoR 화면의 입력 값 및 모델 바인딩

18554 단어 JRubyRubyRails

개시하다


화면의 입력값과 모델의 귀속에 관하여 실험적으로 실현해 보다
Rails 편의점 Gem은 전혀 사용하지 않고 표준 Ruby 라이브러리로만 제공

운영 환경


JRuby 9.1.0
Rails 4.2.9

이루어지다


모델


exam_categori


:column_name=>"ID", :data_type=>"NUMBER"
:column_name=>"CATEGORY_CODE", :data_type=>"VARCHAR2"
:column_name=>"SAKUSEIYMD", :data_type=>"DATE"

exam


:column_name=>"ID", :data_type=>"NUMBER"
:column_name=>"WORD", :data_type=>"VARCHAR2"
:column_name=>"SENTENCE", :data_type=>"CLOB"
:column_name=>"WLEVEL", :data_type=>"NUMBER"
:column_name=>"SAKUSEIYMD", :data_type=>"DATE"
:column_name=>"RENBAN", :data_type=>"NUMBER"
※ ID 중 브라우저 측 랜덤 숫자 설정

스크린


대략적인 방법 설명



대략적인 input 필드 ID 추가 방법



→ input 탭의 id 속성의 명칭 규칙을'모델 이름 # 입력 줄 수. 모델의 열 이름'으로 설정합니다
Ralis에서 POST의 요청 매개 변수를
exam [
 {1=>[wlevel=value,word=value,sentence=value]},
 [2=>{wlevel=value,word=value,sentence=value}] ,
 [3=>{wlevel=value,word=value,sentence=value]} ,
]
데이터 구조

Rails 측 설치


exam_controller.rb
class ExamController< ApplicationController
protect_from_forgery :expect  => ["create"]
    def register
        a = params
        .to_a #--(1)
        .group_by do |k,v| --(2)
            str=k[/^.*#/]
            str.present? ?str.tr("#",""):"" 
        end
        .to_a--(3)
        .select{|k,v|k.present?}--(4)
        .map do|k,v|--(5)
            [k,v.group_by {|a,b|a.scan(/#(\d)/)[0]}]
        end
        puts a
        render text:""
  end
end
(1) 요청 매개변수 "params"정렬
(2) 요청된 매개변수의 키와 일치하는 모델 이름 #을 사용하여 그룹화
(3) (2)의 결과를 배열하다
(4) (2)의 결과에서 키가 nil인 것을 제외한다
즉,params에 포함된 컨트롤러나view 정보를 제외합니다.
(5) (4)에서 변환된 배열을 [모델 이름], {행수=>[화면의 입력 값의 집합]}으로 변환하는 데이터 구조

실행 결과


요청된 매개변수 값

Parameters: 
 {"exam_categori#1.category_code"=>"カテゴリ1", 
  "exam#1.word"=>"テスト1", "exam#1.sentence"=>"テスト1の説明", 
  "exam#1.wlevel"=>"1", "exam#2.word"=>"テスト2", 
  "exam#2.sentence"=>"テスト2の説明", "exam#2.wlevel"=>"2", 
  "exam#3.word"=>"テスト3", "exam#3.sentence"=>"テスト3の説明", 
  "exam#3.wlevel"=>"3", "id#1"=>"799454"}

rails 옆에서 전환한 결과

[
    ["exam_categori", 
        {["1"]=>[["exam_categori#1.category_code", "カテゴリ1"]]}], 
    ["exam", 
        {["1"]=>[["exam#1.word", "テスト1"], 
                 ["exam#1.sentence", "テスト1の説明"], 
                 ["exam#1.wlevel", "1"]], 
         ["2"]=>[["exam#2.word", "テスト2"], 
                 ["exam#2.sentence", "テスト2の説明"], 
                 ["exam#2.wlevel", "2"]], 
         ["3"]=>[["exam#3.word", "テスト3"], 
                 ["exam#3.sentence", "テスト3の説明"], 
                 ["exam#3.wlevel", "3"]]}]
    ["id", 
         {["1"]=>[["id#1", "799454"]]}]
]

참조: 화면 측면 설치


exam.html
<!DOCTYPE html>

<script>
function doPost(){
    var id = Math.floor(Math.random () * 1000000) 
    var param = _g()
    .concat(
       [`id#1=${id}`])
    .join('&')
    commute('http://localhost:3000/exam/register/',param)
}
function commute(url,param){
    var req = new XMLHttpRequest();
    req.open('POST',url , true);
    req.setRequestHeader('content-type',
    'application/x-www-form-urlencoded;charset=UTF-8');
    console.log(param)
    req.send(param);
    req.onload =  _r(req,
        function(){_t('display',req.responseText );});
}
function _r(req,caller){
  return function (event){
    if (req.readyState === 4 && req.status === 200) 
      caller();
  };
}
function _f(str){
    return document.getElementById(str).value;
}
function _t(str,text){
    return document.getElementById(str).innerText=text;
}
function _k(str){
   return Object.keys(document.getElementsByTagName(str))
}
function _g(){
    console.log(_k('input'))
    return _k('input')
    .filter(a=>isNaN(a))
    .map(a=>`${a}=${_f(a)}`)
}


</script>

<body>
<div style="position:relative;left:7pt;padding:10pt;border: 1pt solid #2cbf88;width:600pt">
  <div style="position:relative;left:7pt;padding:10pt;border: 1pt solid #2cbf88;width:400pt">
      カテゴリ:
      <div style="position:relative;left:5pt;padding:5pt"> 
          <input type='text'id='exam_categori#1.category_code' size='50'>
      </div>
  </div>
  <div style="position:relative;left:7pt;padding:5pt;"></div>  
  <div style="position:relative;left:7pt;padding:10pt;border: 1pt solid #2cbf88;width:500pt">
    <div style="position:relative;left:5pt;padding:5pt">
        レベル1:
        <input type='text'id='exam#1.word' size='10'>
        <input type='text'id='exam#1.sentence' size='50'>
        <input type='hidden' id='exam#1.wlevel' value="1">
    </div>
    <div style="position:relative;left:5pt;padding:5pt">
        レベル2:
        <input type='text'id='exam#2.word' size='10'>
        <input type='text'id='exam#2.sentence' size='50'>
        <input type='hidden' id='exam#2.wlevel' value="2">
    </div>
    <div style="position:relative;left:5pt;padding:5pt">
        レベル3:
        <input type='text'id='exam#3.word' size='10'>
        <input type='text'id='exam#3.sentence' size='50'>
        <input type='hidden' id='exam#3.wlevel' value="3">
    </div>
  </div>
</div>
<input type='button' onclick='doPost();' value="登録">
<div id='display'></div>

좋은 웹페이지 즐겨찾기