Backbone Marionette Fetch命中Rails索引动作而非Show

时间:2014-09-08 14:13:27

标签: ruby-on-rails backbone.js marionette

我今天在我的调试参数中注意到,获取时单个Backbone模型正在点击索引操作而不是Show操作。

My Backbone Marionette应用程序从索引视图开始:

index.html.erb

<div id="wrap">
  <div id="header-region"></div>
  <div id="main-region"></div>
  <div id="push"></div>
</div>
<div id="footer-region"></div>
<div id="dialog-region"></div>

<%= javascript_tag do %>
  $(function() {
    SampleApp.start({
      environment: "<%= Rails.env %>"
    });
  });
<% end %>

因为它在索引视图中运行,所以任何提取调用总是会在控制器的索引操作上解析吗?有没有办法可以强制主干模型获取调用来命中控制器的Show动作而不是索引动作?

奇怪的是网络调用在响应中显示/posts/17.json而不是/posts.json我希望在索引视图中看到。然而实际的呼叫似乎正在触及控制器中的索引动作。

编辑:

Approuter:

@SampleApp.module "SurveysApp", (SurveysApp, App, Backbone, Marionette, $, _) ->

  class SurveysApp.Router extends Marionette.AppRouter
    appRoutes:
      ""            : "list"
      ":id"         : "show"
      ":id/take": "take"

  API =
    list: ->
      new SurveysApp.List.Controller

    show: (id, survey) ->
        new SurveysApp.Show.Controller
            id: id
            survey: survey

    take: (id, survey) ->
      new SurveysApp.Take.Controller 
        id: id 
        survey: survey

    newSurvey: (surveys) ->
      new SurveysApp.New.Controller 
        surveys: surveys

  App.vent.on "survey:clicked", (survey) ->
    App.navigate "/" + survey.id
    API.show survey.id, survey

  App.vent.on "new:survey", (surveys) ->
    API.newSurvey surveys

  App.vent.on "take:survey:button:clicked", (survey) ->
    App.navigate "/" + survey.id + "/take"
    API.take survey.id, survey

  App.vent.on "survey:list", ->
    App.navigate "/"
    API.list()

  App.addInitializer ->
    new SurveysApp.Router
      controller: API

型号:

@SampleApp.module "Entities", (Entities, App, Backbone, Marionette, $, _) ->

  class Entities.Survey extends App.Entities.Model
    urlRoot: "surveys"
    url: ->
      if @.get('take') == true
        url = @urlRoot + "/" + @id + "/fetch.json"
      else 
        url = @urlRoot + "/" + @id + ".json"
      return url 

    sync: (method, model, options) ->
     @mySyncFunction method, model, options

    mySyncFunction: (method, model, options) ->
      if (method == 'GET')
        options.url = model.url
      else
        options.url = @urlRoot + "/" + @id + ".json"
      return Backbone.sync(method, model, options)

    defaults: 
      status: "Draft"
      number_taken: 0
      survey_limit: 500
      take: false

    relations: [
      type: Backbone.HasMany
      key: "questions"
      relatedModel: Entities.Question
      reverseRelation: 
        key: 'survey'
        includeInJSON: 'id'
    ]

扩展了这个:

@SampleApp.module "Entities", (Entities, App, Backbone, Marionette, $, _) ->

  class Entities.Model extends Backbone.RelationalModel

    initialize: ->
      @listenTo(@, 'change', @modelChanged)

    modelChanged: ->
      @hasChangedSinceLastSync = true


    sync: (method, model, options) ->
      options = options || {}
      success = options.success
      options.success = (resp) ->
        success && success(resp)
        model.hasChangedSinceLastSync = false
      super method, model, options

    destroy: (options = {}) ->
      _.defaults options,
        wait: true

      @set _destroy: true
      super options

    isDestroyed: ->
      @get "_destroy"

    save: (data, options = {}) ->
      isNew = @isNew()

      _.defaults options,
        wait: true
        success:   _.bind(@saveSuccess, @, isNew, options.collection, options.callback)
        error:    _.bind(@saveError, @)

      @unset "_errors"
      super data, options

    saveSuccess: (isNew, collection, callback) =>
      if isNew ## model is being created
        collection?.add @
        collection?.trigger "model:created", @
        @trigger "created", @
      else ## model is being updated
        collection ?= @collection ## if model has collection property defined, use that if no collection option exists
        collection?.trigger "model:updated", @
        @trigger "updated", @

      callback?()

    saveError: (model, xhr, options) =>
      ## set errors directly on the model unless status returned was 500 or 404
      @set _errors: $.parseJSON(xhr.responseText)?.errors unless /500|404/.test xhr.status

  API =
    newModel: (attrs) ->
      new Entities.Model attrs

  App.reqres.setHandler "new:model", (attrs = {}) ->
    API.newModel attrs

控制器:

class SurveysController < ApplicationController
  before_action :set_survey, only: [:show, :fetch, :edit, :update, :destroy]

  # GET /surveys
  # GET /surveys.json
  def index
    unless signed_in?
      redirect_to signin_path
    end
    @surveys = Survey.where(user_id: cookies[:theoremreach_user_id])
  end

  # GET /surveys/1
  # GET /surveys/1.json
  def show
    respond_to do |format|
      format.json
      format.csv { send_data @survey.to_csv }
      format.xls #{ send_data @survey.to_csv(col_sep: "\t") }
    end
  end

  def fetch
    unless signed_in?
      redirect_to signin_path
    end
    respond_to do |format|
      format.json
    end
  end

  # GET /surveys/new
  def new
    @survey = Survey.new
  end

  # GET /surveys/1/edit
  def edit
    # unless signed_in?
    #   redirect_to signin_path
    # end
  end

  # POST /surveys
  # POST /surveys.json
  def create
    @survey = Survey.new(survey_params)

    respond_to do |format|
      if @survey.save
        if @survey.status == "Submitted"
          SurveyMailer.survey_created(@survey).deliver
        end
        format.html { redirect_to @survey, notice: 'Survey was successfully created.' }
        format.json { render action: 'show', status: :created, location: @survey }
      else
        format.html { render action: 'new' }
        format.json { render json: @survey.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /surveys/1
  # PATCH/PUT /surveys/1.json
  def update
    respond_to do |format|
      if @survey.update(survey_params)
        if @survey.status == "Submitted"
          SurveyMailer.survey_created(@survey).deliver
        end
        format.html { redirect_to @survey, notice: 'Survey was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @survey.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /surveys/1
  # DELETE /surveys/1.json
  def destroy
    @survey.destroy
    respond_to do |format|
      format.html { redirect_to surveys_url }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_survey
      @survey = Survey.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def survey_params
      params.require(:survey).permit(:number_taken, :survey_limit, :title, :status, :user_id)
    end
end

routes.rb中:

resources :surveys

  resources :surveys do 
    get :fetch, on: :member
  end

基本上我正在尝试做的目标是让surveys#1/take点击控制器中的Show动作,不需要用户登录(任何人都应该能够进行调查) ),而调查/ 1或调查索引应分别点击获取/索引操作并需要登录(在编辑/查看调查列表之前/之后)。

现在,调查#1 / take route正在点击控制器上的Index操作,并要求用户登录。

0 个答案:

没有答案