2016-07-21 13 views
-1

Hilfe, bitte! Vielleicht hat jemand schon mit meinem Problem konfrontiert ....Relay re-fetching ist fehlgeschlagen ... error Relay konnte die Kanten einer Verbindung nicht abgleichen

Wenn erneut abzurufen Daten mit der aktualisierten Variablen - mit relay.setVariables() - erhalte ich die Fehler „Relay konnte Kanten auf einem in Einklang zu bringen Dies ist höchstwahrscheinlich beim Versuch aufgetreten, eine Serverantwort zu verarbeiten, die Verbindungskanten mit Knoten enthält, denen kein id-Feld zugeordnet ist. " und Relay-Speicher wird nicht aktualisiert, obwohl die Daten korrekt sind.

Siehe Code unten ... (Rubin & & ES6)

gemfile

gem 'graphql', '0.16.0' 
gem 'graphql-relay', '0.11.2' 

.... serverseitigen Code

node_identification.rb

NodeIdentification = GraphQL::Relay::GlobalNodeIdentification.define do 
object_from_id -> (id, ctx) do 
    type, id = NodeIdentification.from_global_id(id) 
    case type 
     when 'FrontApp' 
      Relay::FrontApp::STATIC 
     else 
      Object.const_get(type).find_by(id: id) 
    end 
end 

type_from_object -> (obj) do 
    begin 
     MODEL_TO_TYPE[obj.class.name.to_sym].constantize 
    rescue 
     (obj.class.name + 'Type').constantize 
    end 
end 
end 

MODEL_TO_TYPE = { 
    :'Relay::FrontApp' => 'FrontAppType' 
} 

front_app_query_type.rb

FrontAppQueryType = GraphQL::ObjectType.define do 
name 'FrontAppRootQuery' 
field :node, field: NodeIdentification.field 

field :main, FrontAppType do 
    resolve -> (obj, args, ctx) { 
     Relay::FrontApp::STATIC 
    } 
end 
end 

front_app_type.rb

FrontAppType = GraphQL::ObjectType.define do 
name 'FrontApp' 
# field :node, field: NodeIdentification.field 
interfaces [NodeIdentification.interface] 
global_id_field :id 

field :tips, TipsType do 
    argument :filters, types.String 
    resolve -> (obj, args, ctx) { 
     filters = args[:filters] 
     begin 
      filters = JSON.parse(filters).deep_symbolize_keys! 
     rescue 
      filters = nil 
     end 
     ctx[:filters] = filters 
     Relay::Tips::STATIC 
    } 
end 
connection :footer, FooterMenuItemType.connection_type do 
    argument :id, types.ID! 
    resolve ->(obj, args, ctx){ 
     ::Footer.order(:id) 
    } 
end 
end 

tips_connection_type.rb

TipsConnectionType = TipShowType.define_connection do 
field :totalCount, types.Int do 
    resolve -> (obj, args, ctx) { 
     obj.object.size 
    } 
end 
end 


TipsType = GraphQL::ObjectType.define do 
name 'Tips' 
description 'Tips list for home page' 
interfaces [NodeIdentification.interface] 
global_id_field :id 

connection :mostRecent, TipsConnectionType do 
    argument :limit, types.Int 
    resolve ->(obj, args, ctx){ 
     tips = ::Tip.active_users.started(Time.zone.now.in_time_zone(ctx[:current_user] ? ctx[:current_user].time_zone : ::User.get_locally_time_zone).to_date).ready.active.moderated.published.includes(:comments, :tip_type).order('created_at desc').limit(args[:limit]) 
     TipHelpers::Filter.filter(tips: tips, filters: ctx[:filters], reorder: 'created_at desc') 
    } 
end 
connection :mostPopular, TipsConnectionType do 
    argument :limit, types.Int 
    resolve ->(obj, args, ctx){ 
     tips = ::Tip.active_users.started(Time.zone.now.in_time_zone(ctx[:current_user] ? ctx[:current_user].time_zone : ::User.get_locally_time_zone).to_date).ready.active.moderated.published.includes(:comments, :tip_type).order('(SELECT COUNT(*) FROM comments WHERE tid = tips.id) desc').limit(args[:limit]) 
     TipHelpers::Filter.filter(tips: tips, filters: ctx[:filters], reorder: '(SELECT COUNT(*) FROM comments WHERE tid = tips.id) desc') 
    } 
end 
end 

/app/Modelle/Relais/fr ont_app.rb

module Relay 
class FrontApp < Struct.new :id 
    # HACK::// For relay root queries 
    STATIC = new(id: 'main').freeze 

    def initialize *args 
     opts = args.last.is_a?(Hash) ? args.pop : Hash.new 
     super *args 
     opts.each_pair do |k, v| 
      self.send "#{k}=", v 
     end 
    end 

    def self.find(_) 
     STATIC 
    end 
end 
end 

** /app/models/relay/tips.rb**

module Relay 
class Tips < Struct.new :id 
    # HACK:// For relay root queries 
    STATIC = new(id: 'tips').freeze 

    def initialize *args 
     opts = args.last.is_a?(Hash) ? args.pop : Hash.new 
     super *args 
     opts.each_pair do |k, v| 
      self.send "#{k}=", v 
     end 
    end 

    def self.find(_) 
     STATIC 
    end 

end 
end 

.... und clientseitigen Code

class MainApp extends React.Component { 

constructor(props) { 
    super(props); 

    this.state = { 
     filters: filtersTemplate 
    }; 

    this.setFilter = this.setFilter.bind(this); 
} 

setFilter(filter, value, e) { 
    if (e) { 
     e.nativeEvent.stopImmediatePropagation(); 
     e.preventDefault(); 
    } 

    let { filters } = this.state; 
    if (['currency', 'sum'].inArray(filter)) { 
     filters.funds[filter] = value; 
    } else { 
     filters[filter] = value; 
    } 
    this.setState({ 
     filters: filters 
    }); 
    this.props.relay.setVariables({filters: filters}); 
} 

render() { 
    let { tips } = this.props.main; 
    let renderTipsSection = (section) => { 
     let tipsCount = tips[section] ? tips[section].edges.length : 0; 
     let blankCount = 10 - tipsCount; 
     return (
      <ul className="tips__list"> 
       { 
        tips[section] && tips[section].edges.map(({node}) => (
         <li key={node.id} className="tips__list_item"> 
          <TipCard node={node}/> 
         </li> 
        )) 
       } 
       { 
        [...new Array(blankCount).keys()].map((item, idx) => (
         <li key={idx} className="tips__list_item"> 
          <TipCard dummy={true}/> 
         </li> 
        )) 
       } 
      </ul> 
     ); 
    }; 
    return (
     <div> 
      <div className="wrapper"> 
       <div className="TipsWrapper"> 
        <div className="wrapper"> 

         { renderTipsSection('mostRecent') } 

         { renderTipsSection('mostPopular') } 

        </div> 
       </div> 
      </div> 
     </div> 
    ); 
}} 

export default Relay.createContainer(MainApp, { 
initialVariables: { 
    filters: { 
     category: null, 
     funds: { 
      currency: null, 
      sum: null 
     }, 
     date: null, 
     location: null, 
     browse: null 
    } 
}, 
prepareVariables: (prevVars) => { 
    return { 
     ...prevVars, 
     filters: JSON.stringify(prevVars.filters) 
    } 
}, 
fragments: { 
    main:() => Relay.QL` 
     fragment on FrontApp { 
      tips(filters: $filters) { 
       mostRecent(first: 10, limit: 10){ 
       edges { 
        node { 
        id 
        tid 
        title_name 
        category 
        } 
       } 
       } 
       mostPopular(first: 10, limit: 10){ 
       edges { 
        node { 
        id 
        tid 
        title_name 
        category 
        } 
       } 
       } 
      } 
     } 
    ` 
}}); 

Wenn setFilter() ausgelöst die Relais.setVariables wird aufgerufen werden ... und Ergebnis ...

[RELAY-NETWORK] Run query q3 Object {relayReqId: "q3", relayReqObj: RelayQueryRequest, relayReqType: "query", method: "POST", headers: Object…} 
[RELAY-NETWORK] query q3: 3429ms 
Warning: Relay was unable to reconcile edges on a connection. This most likely occurred while trying to handle a server response that includes connection edges with nodes that lack an `id` field 
+0

Könnten Sie enthalten den Code für 'TipShowType' auch? (Das ist die "Kante" für die fraglichen Verbindungen, richtig?) – rmosolgo

+0

gesendet an [https://github.com/rmosolgo/graphql-relay-ruby/issues/61](https://github.com/rmosolgo/ graphql-relay-ruby/issues/61) –

+0

Ich löse dieses Problem über die Mutationen mit FIELDS_CHANGE Verhalten –

Antwort

-2

Nach vielen Stunden der Qual Lösung des oben beschriebenen Problems gefunden wurde ... siehe unten

SOLUTION

clientseitige Mutation

export default class ApplyFiltersMutation extends Relay.Mutation { 
static fragments = { 
    tips:() => Relay.QL` 
     fragment on Tips { 
      id 
     } 
    `, 
}; 

getMutation() { 
    return Relay.QL`mutation { 
     applyFilters 
    }`; 
} 

getVariables() { 
    return { 
     filters: this.props.filters 
    }; 
} 

getFatQuery() { 
    return Relay.QL` 
     fragment on ApplyFiltersPayload { 
      tips 
     } 
    `; 
} 

getConfigs() { 
    return [ 
     { 
      type: 'FIELDS_CHANGE', 
      fieldIDs: {tips: this.props.tips.id}, 
     } 
    ]; 
} 
} 

serverseitige

ho me_mutationen. rb

module HomeMutations 
    ApplyFilters = GraphQL::Relay::Mutation.define do 
    name 'ApplyFilters' 
    input_field :filters, !types.String 

    return_field :tips, BipsType 

    resolve -> (args, ctx) { 
     filters = args[:filters] 
     begin 
      filters = JSON.parse(filters).deep_symbolize_keys! 
     rescue 
      filters = nil 
     end 
     ctx[:filters] = filters 

     { 
      tips: Relay::Tips::STATIC 
     } 
    } 
    end 
end 

tips_type.rb

include TipHelpers::Filter 

TipsType = GraphQL::ObjectType.define do 
name 'Tips' 
description 'Tips list for home page' 
interfaces [NodeIdentification.interface] 
global_id_field :id 

connection :almostRaised, TipsConnectionType do 
    resolve ->(obj, args, ctx){ 
     TipHelpers::Filter.filter(section: 'almost_raised', filters: ctx[:filters], current_user: ctx[:current_user]) 
    } 
end 

... 

end 
end 

lib/tip_helpers.rb

class TipHelpers 
module Filter 

    def filter(section:, filters:, current_user:) 

     ... 

     # p tips.reorder(reorder).to_sql 
     tips.reorder(reorder) 
    end 
end 
end 
+1

Könnte die Antwort angeben, wo genau die Lösung angewendet wurde? – minheq