diff --git a/app/models/node_function.rb b/app/models/node_function.rb index e783768d..6c275494 100644 --- a/app/models/node_function.rb +++ b/app/models/node_function.rb @@ -38,8 +38,35 @@ def to_grpc Tucana::Shared::NodeFunction.new( database_id: id, runtime_function_id: function_definition.runtime_function_definition.runtime_name, - parameters: node_parameters.map(&:to_grpc), + parameters: ordered_parameters.map(&:to_grpc), next_node_id: next_node&.id ) end + + def ordered_parameters + fd = FunctionDefinition.arel_table + rfd = RuntimeFunctionDefinition.arel_table + rpd = RuntimeParameterDefinition.arel_table + np = NodeParameter.arel_table + pd = ParameterDefinition.arel_table + + NodeParameter + .from(fd) + .joins( + fd + .join(rfd, Arel::Nodes::InnerJoin) + .on(fd[:runtime_function_definition_id].eq(rfd[:id])) + .join(rpd, Arel::Nodes::InnerJoin) + .on(rfd[:id].eq(rpd[:runtime_function_definition_id])) + .join(pd, Arel::Nodes::InnerJoin) + .on(rpd[:id].eq(pd[:runtime_parameter_definition_id])) + .join(np, Arel::Nodes::InnerJoin) + .on(np[:parameter_definition_id].eq(pd[:id])) + .join_sources + ) + .where(fd[:id].eq(function_definition_id)) + .where(np[:node_function_id].eq(id)) + .order(rpd[:id].asc) + .select(np[Arel.star]) + end end diff --git a/lib/sagittarius/graphql/stable_connection.rb b/lib/sagittarius/graphql/stable_connection.rb index 2e49a3f1..ffc96cbd 100644 --- a/lib/sagittarius/graphql/stable_connection.rb +++ b/lib/sagittarius/graphql/stable_connection.rb @@ -24,7 +24,7 @@ def results @results ||= begin if backward? paginate_backward - elsif @after_value.present? + else paginate_forward end @@ -43,10 +43,13 @@ def paginate_backward end def paginate_forward - after_id = Integer(decode(@after_value), exception: false) - raise GraphQL::ExecutionError, "Invalid cursor '#{@after_value}' provided" if after_id.nil? + unless @after_value.nil? + after_id = Integer(decode(@after_value), exception: false) + raise GraphQL::ExecutionError, "Invalid cursor '#{@after_value}' provided" if after_id.nil? + end - @items = @items.where(id: (after_id + 1)..).order(id: :asc) + @items = @items.where(id: (after_id + 1)..) unless after_id.nil? + @items = @items.order(id: :asc) end def nodes diff --git a/spec/models/flow_spec.rb b/spec/models/flow_spec.rb index 37ee710f..03900d11 100644 --- a/spec/models/flow_spec.rb +++ b/spec/models/flow_spec.rb @@ -37,19 +37,32 @@ end before do + runtime = create(:runtime, namespace: flow.project.namespace) + rfd = create(:runtime_function_definition, runtime: runtime) + fd = create(:function_definition, runtime_function_definition: rfd) + rpd = create( + :runtime_parameter_definition, + runtime_function_definition: rfd, + data_type: create( + :data_type_identifier, + generic_key: 'T' + ) + ) + pd = create( + :parameter_definition, + function_definition: fd, + runtime_parameter_definition: rpd, + data_type: rpd.data_type + ) + func = create( :node_function, + function_definition: fd, flow: flow, node_parameters: [ create( :node_parameter, - parameter_definition: create( - :parameter_definition, - data_type: create( - :data_type_identifier, - generic_key: 'T' - ) - ) + parameter_definition: pd ) ] ) diff --git a/spec/models/node_function_spec.rb b/spec/models/node_function_spec.rb index c63b04ac..fde30735 100644 --- a/spec/models/node_function_spec.rb +++ b/spec/models/node_function_spec.rb @@ -13,4 +13,95 @@ it { is_expected.to have_many(:node_parameter_values).inverse_of(:function_value) } it { is_expected.to have_many(:node_parameters).inverse_of(:node_function) } end + + describe '#ordered_parameters' do + let(:runtime) { create(:runtime) } + + let(:data_type_identifier) do + create( + :data_type_identifier, + data_type: create(:data_type, runtime: runtime) + ) + end + + let(:runtime_function_definition) do + create( + :runtime_function_definition, + runtime: runtime + ).tap do |rfd| + rfd.parameters << create( + :runtime_parameter_definition, + runtime_function_definition: rfd, + runtime_name: 'param1', + data_type: data_type_identifier + ) + + rfd.parameters << create( + :runtime_parameter_definition, + runtime_function_definition: rfd, + runtime_name: 'param2', + data_type: data_type_identifier + ) + + rfd.parameters << create( + :runtime_parameter_definition, + runtime_function_definition: rfd, + runtime_name: 'param3', + data_type: data_type_identifier + ) + end + end + + let(:function_definition) do + create( + :function_definition, + runtime_function_definition: runtime_function_definition + ) + end + + let(:node_function) do + create( + :node_function, + function_definition: function_definition + ).tap do |node| + node.node_parameters << create( + :node_parameter, + node_function: node, + parameter_definition: create( + :parameter_definition, + data_type: data_type_identifier, + runtime_parameter_definition: runtime_function_definition.parameters[1] + ) + ) + node.node_parameters << create( + :node_parameter, + node_function: node, + parameter_definition: create( + :parameter_definition, + data_type: data_type_identifier, + runtime_parameter_definition: runtime_function_definition.parameters[2] + ) + ) + node.node_parameters << create( + :node_parameter, + node_function: node, + parameter_definition: create( + :parameter_definition, + data_type: data_type_identifier, + runtime_parameter_definition: runtime_function_definition.parameters[0] + ) + ) + end + end + + it 'orders node parameters as in runtime function definition' do + expect(node_function.ordered_parameters.to_a).to eq( + [ + node_function.node_parameters[2], + node_function.node_parameters[0], + node_function.node_parameters[1] + ] + ) + end + end end