2014-02-25 1 views
2

저는 루비와 레일스가 처음이기 때문에 제가하고 싶은 일에 더 나은 접근법을 제시합니다. 다른 접근법이 어떻게 생겼는지보다 내가 사용하고 있습니다 :레일스 ActiveRecord.new는 기존 레코드를 업데이트하는 대신 새로운 레코드를 생성합니다.

  • 루비 1.8.7
  • 레일 3.2.12
  • 레드 마인 2.2.3 (이다 나는 생각하지 않지만 여기 전혀 관련)
  • MySQL의 5.6

필자는 Skin.rb 모델 (외장은 외관이 아니라 기관이 아님)과 Android 환경을위한 하나의 스킨과 iOS 환경을위한 다른 스킨을 가지고 있습니다. 스킨에는 연관된 0 개 또는 하나의 언어 파일과 그와 연관된 0 개 또는 1 개의 그래픽 파일이있을 수 있습니다. 이러한 스킨 속성은 스킨의 각을 나열하는 응용 프로그램 \ 전망 \ 스킨 \ index.html.erb보기에 표시됩니다 나도 안드로이드의 속성을 업데이트 할 수 있도록하고 싶습니다

<% @skins.each do |skin| %> 
    <% if skin.device_os == 'android' %> 
    <%= content_tag(:h3, 'Android') %> 
    <% elsif skin.device_os == 'ios' %> 
    <%= content_tag(:h3, 'iOS') %> 
    <% end%> 

<table> 
    <thead><tr> 
     <td>Languages</td> 
     <td>Graphics</td> 
     <td></td> 
     <td></td> 
    </tr></thead> 

    <tbody>  
     <tr> 
     <%= form_for :skin, :url => skins_path do |f| %> 
      <td><%= f.collection_select :lang_file, (Attachment.find_by_sql [@lang_file_sql, @current_project.id]), :id, :filename, {:prompt => skin.lang_file.present? ? Attachment.find(skin.lang_file).filename : "Select a languages file"} %></td> 
      <td><%= f.collection_select :graphics_pack, (Attachment.find_by_sql [@graphics_pack_sql, @current_project.id]), :id, :filename, {:prompt => skin.graphics_pack.present? ? Attachment.find(skin.graphics_pack).filename : "Select a graphics pack"} %></td> 
      <td><%= hidden_field('skin', 'id', {:value => skin.id}) %></td> 
      <td><%= f.submit %></td> 
     <% end %> 
     </tr> 
    </tbody> 
    </table> 
<% end %> 

스킨 또는 iOS 스킨을 업데이트하고 스킨 테이블의 해당 레코드를 업데이트합니다. 그러나 레코드를 시도하고 업데이트 할 때 업데이트되는 관련 레코드 대신 새 레코드가 만들어집니다.

나는이 작업을 수행하기 위해 노력하고있어 방법은 skins_controller#create 방법의 id 업데이트 lang_filegraphics_pack 속성 인덱스보기에서 업데이트 된 피부를 전달하는 것입니다. 에 WEBrick에 의해 추적과 같이 POST는 다음과 같습니다 : 당신은 위의 전달 params[:skin] 매개 변수를 볼 수 있습니다

Started POST "/skins" for 127.0.0.1 at Tue Feb 25 15:25:04 +0000 2014 
Processing by SkinsController#create as HTML 
    Parameters: {"authenticity_token"=>"sZWVl8IO1IKRNa/fStps8pUehDcSqQsaN/vpL3BITf8=", "commit"=>"Save 
Skin", "utf8"=>"Ô£ô", "skin"=>{"lang_file"=>"6", "graphics_pack"=>"", "id"=>"4"}} 

.

이 메서드는 new 메서드를 사용하여 전달되는 특성이 params[:skin] 인 새 Skin 개체를 만듭니다.

def create 
@skin = Skin.new(params[:skin]) #@skin{ id: => 4, lang_file: => 6, graphics_pack => nil } 
if @skin.save #update skins table if record with skins.id=4 already exists else create new record 
    redirect_to :back 
else 
    # do error handling stuff 
end 
end 

를 지금까지 내가 이해, skin.idskins 테이블에 대한 기본 키, save 작품 (단순하게) 다음과 이후 : 다음과 같이 create 방법은 (코멘트 위의 추적에 WEBrick 참조) 보이는

  1. 현재 그래서 새 그래서 그 기록은 POST의 REQ에 그에 따라 설정된 속성으로 업데이트됩니다 skins.id = 4 레코드가 이미 있습니다
  2. 생성 skins.id = 4에 대한 기록이 없다 ~.

http://apidock.com/rails/ActiveRecord/Base/save 모래 rails activerecord save method 나는 모두 옳은 일을하고 있지만 작동하지 않는다고 제안합니다.

기존 스킨 중 하나를 구성하려고 할 때마다 스킨 테이블에 새 스킨 레코드가 만들어지고 마지막으로 생성 된 스킨 테이블에서 자동으로 증가 된 skins.id이 자동으로 증가합니다. params[:skin][:id]은 무시됩니다.

필요에 따라 newsave 방법을 사용하여 새 레코드를 업데이트/생성 할 수 있습니까? 어떻게해야합니까?SkinsController#create 메서드 자체에 대한 대답을 기대하고 있으므로 SkinsController에 충분한 정보를 전달하고 있다고 생각합니다.

(아마도 더 나은 방법이있을 때 왜 이런 식으로하고 있어요에 관해서는 :
  1. 내 사용 사례

    이미 시간 사용자가 안드로이드 피부와 아이폰 OS 피부가되어야한다는 등이다가 http://.../skins
  2. 으로 이동합니다. 언어가 허용하는 경우이 코드를 업데이트/작성하면 좋겠다고 생각합니다. 따라서 다양한 업데이트 방법을 레일에서 피할 수 있습니다 (예 : update_attributes). 그래도 save을 둘러 싸면됩니다.)

나는 다른 접근법이 더 좋을 수도 있지만 내 코드가 어떻게 실패하고 있는지 이해하고 싶습니다.

+1

대회는 귀하의 컨트롤러에 편집 및 업데이트 방법을 넣는 것입니다. new를 사용하여 객체 속성을 업데이트하고 컨트롤러 메소드를 생성하는 것이 현명한 방법이라고 생각하지 않습니다. –

+1

리소스 경로를 생성 할 때 별도의 새로운 작성, 편집 및 업데이트 경로가 설정된다는 사실은 한 가지 방법으로 새 ​​스킨을 만들고 다른 방법으로 기존 스킨을 업데이트해야 함을 의미합니다. 그러나 사용자 관점에서 볼 때 버튼 하나만 있으면 새 스킨 또는 업데이트 된 스킨 중 하나가 있어야합니다. first_or_create 메소드 (감사합니다 Vimsha)가 있기 때문에 모든 것을 하나의 메소드에 넣을 수 있습니다.이 메소드는 더 간결하게 만들고 읽을 수있는 방식으로 만듭니다. 하지만 create 대신 SkinController.update 메서드를 사용해야합니다. – user3337410

답변

0

사용 first_or_create

def create 
@skin = Skin.where(:id => params[:skin][:id]).first_or_create #@skin{ id: => 4, lang_file: => 6, graphics_pack => nil } 
if @skin.update_attributes(params[:skin]) #update skins table if record with skins.id=4 already exists else create new record 
    redirect_to :back 
else 
    # do error handling stuff 
end 
end 

params[:skin][:id]은 그 보호 특성 때문에 무시 얻을 것이다. 대량 할당 할 수 없습니다 id

skin = Skin.new(:id => 1, :lang_file => 6) #id will be ignored and autoincremented while saving 
skin.id = 3 #this will work. id will be set to 3 
+0

위대한, 그 일했다! 감사. – user3337410

+0

정답으로 선택하십시오. – usha