2017-09-15 4 views
0

진공 보석 (v. 2.0.2)을 사용하여 Amazon에서 정보를 요청하려고합니다. 그러나 나는 내가 얻은 결과를 어떻게 돌려 보내야할지 확신하지 못한다. 현재, 내 방법이 코드를 만들었 :Ruby 모델에서 변수를 반환하지 않는 메소드

def self.isbn_lookup(val) 
    request = Vacuum.new('US') 
    request.configure(
    aws_access_key_id: 'access_key_goes_here', 
    aws_secret_access_key: 'secret_key_goes_here', 
    associate_tag: 'associate_tag_goes_here' 
) 
    response = request.item_lookup(
    query: { 
     'ItemId' => val, 
     'SearchIndex' => 'Books', 
     'IdType' => 'ISBN' 
    }, 
    persistent: true 
) 
    fr = response.to_h #returns complete hash 
    if fr["ItemLookupResponse"]["Items"]["Item"]["ItemAttributes"]["Author"] 
    @author = fr.dig("ItemLookupResponse","Items","Item","ItemAttributes","Author") 
    end 
    if fr["ItemLookupResponse"]["Items"]["Item"]["ItemAttributes"]["Author"] 
    @title = fr.dig("ItemLookupResponse","Items","Item","ItemAttributes","Title") 
    end 
    if fr["ItemLookupResponse"]["Items"]["Item"]["ItemAttributes"]["Manufacturer"] 
    @manufacturer = fr.dig("ItemLookupResponse","Items","Item","ItemAttributes","Manufacturer") 
    end 
    if fr["ItemLookupResponse"]["Items"]["Item"]["ItemAttributes"][6]["URL"] 
    @url = fr.dig("ItemLookupResponse","Items","Item","ItemLinks","ItemLink",6,"URL") 
    end 
end 

내 컨트롤러에서이 방법에서 만든 변수를 사용할 수 호출하고 싶습니다. 내 컨트롤러에서 저자, 제목, 제조업체 및 URL 인스턴스 변수에 액세스하려면 어떻게합니까? 사용자가 ISBN을 입력 할 때 AJAX 요청을 서버에 전송하여 관련 정보 (작성자, 제목 등)를 요청할 수 있도록하고 싶습니다.

def create 
    @listing = Listing.new(listing_params) 
    @listing.user = current_user 
    if @listing.save 
    flash[:success] = "Your listing was successfully saved." 
    redirect_to listing_path(@listing) 
    else 
    render 'new' 
    end 
end  
def edit 
    @isbn = Listing.isbn_lookup(1285741552) 
end 
+2

인스턴스 변수가 설정되지 않습니다. 'return fr' 줄이 보입니까? 그 라인 이후의 모든 것은 결코 실행되지 않습니다. –

+0

확인. 나는 코드를 업데이트했다. –

+0

그러나 내가 찾은 모든 변수를 반환하도록하려면 어떻게해야합니까? 그런 다음 컨트롤러에서 어떻게 구현합니까? –

답변

2

빠른 수정이 방법은 PORO (일반 오래된 루비 객체)로 값을 반환 한 후 컨트롤러의 인스턴스 변수에 할당 할 수 있도록하는 것입니다 : 현재이 내 컨트롤러는 모습입니다. isbn_lookup 방법의 끝에서,이를 넣어 :

return {title: title, author: author, manufacturer: manufacturer, url: url} 

isbn_lookup 방법으로 인스턴스 변수를 사용하지 마십시오 - 그들은 당신이 그들을 거기에서 원하는 방식으로 작동하지 않습니다. Ruby 클래스가이를 이해하는 방법에 대해 조금 더 배워야 할 수도 있습니다. 그러나 컨트롤러 메서드는 컨트롤러의 인스턴스 (각 요청마다 하나의 인스턴스가 생성됨)에서 실행되며 isbn_lookup클래스 메서드으로 작성되므로 인스턴스 변수가 실제로 의미가 없습니다. 자세한 내용은 Using Instance Variables in Class Methods - Ruby을 참조하십시오.

이렇게 모든 키를 나열하는 것이 바람직하지 않다고 생각하면 점진적으로 개체를 만들 수 있습니다. isbn = {} 두는 방법의 시작 후 isbn[:author] = fr.dig(...) 좋아 단부 return isbn

으로 컨트롤러 방식으로 재료를 수행

@isbn = Listing.isbn_lookup(1285741552) 
@title = @isbn[:title] 
@manufacturer= @isbn[:manufacturer] 
@author = @isbn[:author] 
@title = @isbn[:title] 

@title, @manufacturer 등 인스턴스 변수의 설정 종류 보기에서 단지 @isbn[:author]을 사용할 수 있기 때문에 불필요합니다. 당신의 후속 질문에 응답


:

이 바로 여기 홀수 :

if fr["ItemLookupResponse"]["Items"]["Item"]["ItemAttributes"][6]["URL"] 
    @url = fr.dig("ItemLookupResponse","Items","Item","ItemLinks","ItemLink",6,"URL") 
end 

난 당신이 작품을 발굴하는 방법을 이해 모르겠어요. 중첩 된 객체를 파헤 치는 방법은 입니다. 인수에있는 키의 항목이없는 경우 nil을 반환합니다. 예 : {}.dig(:a, :b, 1, 2, :etc) == nil.

url = fr.dig("ItemLookupResponse","Items","Item","ItemLinks","ItemLink",6,"URL") 
if url 
    # etc 

을하거나 인라인 할당을 사용하기 : 그래서 당신은이 작업을 수행 할 수있는 "? 당신은 == 의미 않았다"당신은 본질적으로 말하는 루비에서 경고를 얻을 수 있지만

if url = fr.dig("ItemLookupResponse","Items","Item","ItemLinks","ItemLink",6,"URL") 
    # etc 

을 (당신은하지 않았다).

여기에 조건부가 실제로 필요한 것은 아닙니다.예를 들어 url이 nil이라해도 메소드가 여전히 :url 키를 가진 해시를 반환하게 할 수 있습니다. 그렇다면 어디서나 실제로은 URL이 존재하는지 여부를 알 필요가 있습니다 (예 :보기, 프레젠테이션 목적으로) if @isbn[:url]

+0

그래, 내가 이것을 사용할 때 어떤 이유에서든, 다음과 같은 에러가 난다 : "정의되지 않은 메소드'[] 'for nil : NilClass." 나는 이것이 url 변수에 대한 숫자로 요소를 참조하는 방식 일 것이라고 생각한다. 이 오류를 방지하는 쉬운 방법은 없습니까? –

+1

@JackMoody는 답을 업데이트합니다. –