Tabish Iqbal

Joined

5,790 Experience
15 Lessons Completed
5 Questions Solved

Activity

Posted in Incorrect setup for Model associations

Posted in Just want to say thanks!

Congrats!

Stephen

Omg, that worked!
Thats brilliant.

Chris you're awesome. I love you man. (his real words / feelings)

Chris

I haven’t actually used the location header with vue-resource so you may have to access it some different way
or you can put it into the json
nevermind, looks easy: Turbolinks.visit(response.headers.get('Location'));

Chris

just pass the url into location
format.json { render json: @proposal, location: [@project, @proposal] } will probably work too

Stephen

Ahhh, ok cool. Can you do nested resources with the JSON response? So at the moment, I wanted to redirect to something like /projects/121/proposals/24

Or do I need to create an unnested route for the proposal show action?

Chris

you should do
format.json { render json: @proposal }

think of it this way
Javascript submits the form to Rails
JS tells it that it wasnt JSON in return
so Rails says okay cool, and calls the format.json block
it needs to render JSON to send back so the Javascript can parse it
and then the JS can redirect using Turbolinks.visit()
you have to include a url of some sort in the JSON back so it can know where to go

one simple thing is to do like
format.json { render json: @proposal, location: @proposal } (edited)
the location will set a url in the HTTP location header you can use to redirect
and still give you the json data of the proposal
but your error from rails said there was no resources :proposals in your routes
so it can’t make that url
you’ll have to fix that or change the url

Stephen

wait a sec, are you referring to this:
format.json { render :show, status: :created, location: @proposal } in the proposal create action?

Chris

you’re submitting the form with Vue-resource / axios
and it wants JSON back
you should see the request in rails say “as JSON”
right?

PROPOSAL JSON

var project = JSON.parse(element.dataset.project)
      var proposal = JSON.parse(element.dataset.proposal)
      var sectionsAttributes = JSON.parse(element.dataset.sectionsAttributes)
      var costItemsAttributes = JSON.parse(element.dataset.costItemsAttributes)
      var milestonesAttributes = JSON.parse(element.dataset.milestonesAttributes)
      var feedback = JSON.parse(element.dataset.feedback)

      proposal.sections_attributes = sectionsAttributes
      proposal.cost_items_attributes = costItemsAttributes
      proposal.milestones_attributes = milestonesAttributes

Stephen

Hey @excid3 I’m doing a standard rails show view (not Json’d), but in terms of the JSON parsing, does this help?

Chris:
what is your json look like
it is trying to do a proposal_url but you don’t have a route for it?

Out of interest, have a weird issue. Trying to do a redirect after create. The record is being created just fine, but get a 500 error on the redirect? Using an ajax call using Vue-resource. Below is the code. (gist for better readability : https://gist.github.com/tabishiqbal/6c3839e53b5c5d34f0cbcc98185bb326)

CREATE METHOD IN CONTROLLER

def create
  @proposal = @project.proposals.create(proposal_params)
  authorize @proposal
  respond_to do |format|

    if @proposal.save!
      format.html { redirect_to project_proposal_path(@proposal.project, @proposal), notice: "Proposal successfully created and submitted to the client" }
      format.json { render :show, status: :created, location: @proposal }
      @project.update_attribute(:status_id, set_quote_ready)

      # As there is a new final, all previous versions are no longer current
      @project.proposals.where.not(id: @proposal.id).update_all(current: false)

      # Set this new final version as the current version
      if @project.proposals.all_final.count > 1
        @user.notify_user("#{@project.supplier.display_name} has updated their proposal. Check it out!", @project.id)
        @project.supplier.notify_business("Your revised proposal has been submitted to the client for approval", @project.id)
      else
        @user.notify_user("#{@project.supplier.display_name} has submitted a proposal for your project. Accept it to start the project", @project.id)
        @project.supplier.notify_business("Your proposal has been submitted to the client for approval", @project.id)
      end

      #UserMailer.new_proposal(@project.user).deliver_now
    else
      format.html { render :new, notice: "Proposal could not be saved" }
      format.json { render json: @proposal.errors, status: :unprocessable_entity }
    end
  end
end

SAVE METHOD IN VUE

saveProposal: function(final) {
    this.$validator.validateAll()

    if (!this.errors.any()) {

        this.saving = true

        if (final == true ) {

            this.proposal.final = true

        } else {

            this.proposal.final = false

        }

        for (var i = 0; i < proposal.milestones_attributes.length; i ++) {

            var ms = proposal.milestones_attributes[i]

            ms.dependencies_attributes = ms.dependencies
            console.log(ms)

        }

        this.$http.post('/projects/' + this.proposal.project_id + '/proposals', {
            proposal: proposal
        })

        .then(function (response) {
            console.log('Saved successfully')
            Turbolinks.visit('/projects/' + this.project.id + '/proposals/${response.body.id}')
        })

        .catch(error => {
            console.log('Error saving proposal. Please correct the errors')
            this.saving = false
        });

** VIEW**

<%= content_tag :div,
  id: "proposal-form",
  data: {
    project: @project.to_json(include: [:industry, :addons, :features, :budget, :type]),
    proposal: @proposal.to_json(except: [:created_at, :updated_at]),
    sections_attributes: @proposal.sections.to_json(except: [:proposal_id, :created_at, :updated_at]),
    cost_items_attributes: @proposal.cost_items.to_json(except: [:proposal_id, :created_at, :updated_at]),
    milestones_attributes: @proposal.milestones.to_json(except: [:proposal_id, :created_at, :updated_at], include: (:dependencies)),
    feedback: @feedback.to_json
  } do %>

<% end %>

PROPOSAL PARAMS

def proposal_params
    params
      .require(:proposal)
      .permit(
        :project_id,
        :supplier_id,
        :version,
        :final,
        :accepted,
        :accepted_at,
        :current,
        billing_phases: [],
        sections_attributes: [
          :id,
          :title,
          :body
        ],
        cost_items_attributes: [
          :id,
          :name,
          :category,
          :timing,
          :price,
          :quantity,
          :taxable,
          :tax,
          :gross,
          :net
        ],
        milestones_attributes: [
          :id,
          :name,
          :due_date,
          :done,
          dependencies_attributes: [
            :id,
            :name,
            :due_date,
            :done
          ]
        ]
      )
      .merge(
        project_id: @project.id,
        supplier_id: @project.supplier_id,
        user_id: @project.user.id,
        version: @version,
        current: true
      )

  end

Posted in Use select_tag to link to customer show page

Sorry at work again but it's hitting your show action in the controller. In there it will redirect to the page where the customer is. You need it to render json? Would be easier if you can gist your code

Posted in Use select_tag to link to customer show page

Sorry at work so I'll kinda explain - but you have to go through the rails guides to better understand how to use ajax / json etc to display data (via javascript).

In your index.html.erb you want to display a record based on what you select from the drop down. so something I have used in the past is where I have a table of all the users (not a drop down) and then a card on the side that is fixed on the page and when I click on the table row it will update the card with the content. You would have to write js to get the value that was selected from the dropdown, get that data's info and then display it.

Here is a gist of stuff I have used before: https://gist.github.com/tabishiqbal/583d4ab9d3db24b4b8bd4c98fc3f1e51

Posted in Use select_tag to link to customer show page

where is your javascript code? or loading the data using ajax? especially if you're displaying it on the index page it'll be done via ajax.

your SaaS app will have more than one table. Ex. Users table, Employees Table, Org Table. You mean you want a multi-tenant app where each companies data is separate from the others. Few ways to do this:

  1. one db for all your customers but scope via tentant_id or company_id etc
  2. one app but each customer gets their own db instance (expensive)
  3. postgres schema - if you use postgres as your db then you can have one db but separate schemas for each customer.

Gems you can use:

  1. https://github.com/influitive/apartment
  2. https://github.com/ErwinM/acts_as_tenant
  3. https://github.com/jekuno/milia

if you really want to learn how to build this you can also look at the following book: https://leanpub.com/multi-tenancy-rails

OR

check out Chris's video on the apartment gem (search in episodes)

Posted in Question BEST_IN_PLACE

are you using a frontend framework? like Vue. If so you can do it that way. Or you can use something like : https://www.froala.com/wysiwyg-editor/inline but its paid. Or I think best_in_place gem is upgrading to work with rails 5.

and there are other things like

https://www.editstrap.com/#demoId
https://vitalets.github.io/bootstrap-editable/
https://vitalets.github.io/x-editable/
http://shokai.github.io/jQuery.editable/

It's got its up's and down's. you start to use it and you're like wth??? then you're like oohhhh I like this and then back to wth?? just seems bloated and all over the place for example this is some html i wrote out. Pretty ugly sometimes...but useful.

<a  class="user-name"
    ng-href="{{ $ctrl.activity.actor.objectUrl }}"
    ng-click="$ctrl.handleClick( 'user-name' )">
    {{ $ctrl.activity.actor.n }}
</a>
<a  ng-href="{{ $ctrl.activity.actor.objectUrl }}"
    class="brand-name"
    ng-click="$ctrl.handleClick( 'brand-name' )">
    {{ $ctrl.activity.actor.o[0].i }} at {{ $ctrl.activity.actor.o[0].n }}
</a>

Been working with Angular 1.5 for the past few months and not really a fan. Yes it makes things easy with having ng-if and ng-click etc but I think using React or Vue.js would be much better.

logo Created with Sketch.

Ruby on Rails tutorials, guides, and screencasts for web developers learning Ruby, Rails, Javascript, Turbolinks, Stimulus.js, Vue.js, and more. Icons by Icons8

© 2021 GoRails, LLC. All rights reserved.