Activity
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
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
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
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:
- one db for all your customers but scope via tentant_id or company_id etc
- one app but each customer gets their own db instance (expensive)
- 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:
- https://github.com/influitive/apartment
- https://github.com/ErwinM/acts_as_tenant
- 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.
Hey Chris.
I have been trying to look online but haven't been successful in finding out the following. Say you made a CRM application in Rails and setup a pop3/imap email in the app. How would you take that email and associate it with a contact? If anyone has worked with Gmail Api - how do companies sync emails to contacts/companies with their apps?
Posted in Import a CSV with associations?
Robert - what was the solution? If you could paste it, it would def. help others here...
Hey,
Sometimes the way .on page:load and on ready work are a little different with Turbolinks. Best way to deal with it as following:
var ready = function () {
// your code goes here
}
$(document).ready(ready);
$(document).on('page:load', ready);
Trying using that and see if it works.
Hey.
Use https://gist.github.com/ You can put all your code nicely in there and its easier to read plus others can edit (revisions) so you can see how it changed.
For db stuff with categories I find using tags easier sometimes. When the user can have multiple treatments you can add on multiple tags ( https://github.com/mbleigh/acts-as-taggable-on ). That way when you are viewing the user you would see all the tags (treatments) the user has or wants to get.
Another approach can be you have a treatments table. In that table you can have a list of all your treatments that the user can select via check boxes.
Also, this is a good read: http://guides.rubyonrails.org/association_basics.html I know when I started I just winged stuff until I started reading all the docs and guides to see how things work (I still don't know squat but I can still make an app based on docs, guides, stackoverflow, gorails, etc)
I'm sure Chris can chime in and probably give a better answer!