Jacob Montgomery


34,500 Experience
33 Lessons Completed
41 Questions Solved


Posted in DB Structure for custom forms

Hey Luca, 

Thanks for the link! I had that same article bookmarked from a while back but never made it back to it, haha!

I think I have a better idea of what you're talking about here now, so I still think the need for multiple forms to be attached to a single record could be accomplished by just adding another layer to the json you store as I previously mentioned... you'll just have to do a little more work to make sure it's the proper version being fetched.

As for your other issue: I would like to move from this method as it has some limitations, one being that by modifying the form template (i.e. adding/removing fields) every existing record should be also modified.

I really have a bad feeling about handling it this way. If you add a new field to a form, then every old form would be updated to just have a nil value since it would require the user to come back to the form and update it. If you remove a field, then once every other record is updated, that data is gone for good (unless you do a soft delete, but that's a whole new issue), so a simple mistake (accidentally deleted the wrong field) could have a horrific ripple effect. So I think if you instead just did versions of a form, you could add or remove fields without being so destructive.

However, there could be some legit reasons to have this ability, but I'm really not sure of a good way to handle this "automagically" without doing what I mentioned in my first response by making a method that checks if a field has been added or removed upon save, and then go through each saved record and adjust the saved json string accordingly. I just don't know of any other way for the database to know a value in a json string has changed and therefore must update every other instance of that particular form that has been submitted previously. If you figure this out, please come back and share!
Oh, duh I didn't pay attention to your book_params, it includes authors_attirbutes.

If this were my project, right or wrong, I'd make two sets of params, one for author and one for book. So something like:

def book_params

def author_params
  params.require(:book).permit(authors_attributes: [:id, :name, :_destroy])

This way you can create your book without the rails magic also creating the association when you create the book when passing book_params.

There could be a better way to handle this scenario that rails provides, but I haven't found it so I usually resort to this sort of setup to get the job done.
Hey Nino, 

I haven't tested this, but I believe this should work for you on your create method:

@book = current_user.books.create(book_params)

author = Author.find_or_create_by(name: "foo") do |author|
  # do stuff if author is new

@book.book_authors.create(author_id: author.id)

find_or_create_by will either create and return a new object or return the found object. So once you have the author object, just create the @book.book_authors record directly.

Posted in DB Structure for custom forms

Hey Luca, 

No problem, sorry nothing was of more help, definitely sounds like it's above my current level!

Do you have any material that you've been specifically referencing as you've been building / working with this setup that you would mind sharing? Your setup really has me curious as to how it all works and I'd love to do some reading on the subject if you have it readily available!

Thanks, and good luck! :)

Posted in DB Structure for custom forms

Hey Luca,

Here are just a few thoughts FWIW, I haven't done much with form templating so that may be a specific use case that nullifies everything below...

... by modifying the form template (i.e. adding/removing fields) every existing record should be also modified.

If you have your associations set up, then just create an update function that goes through each form that used that template and update accordingly for the changes made to the template. There may be a more efficient way to handle this if you're dealing with thousands of records that need to be updated at once.

I would like to attach multiple forms to a single record

Structure your JSON with versions, this should allow you to store as many forms in a single record as you want. So for example, instead of:

data => {
  foo => value,
  bar => value

You could do something like:

data => {
    form_1 => {
      foo => value,
      bar => value,
    form_2 => {
      baz => value

I am also not sure JSON string manipulation is the right/most efficient way
Are you experiencing any specific performance hits or are you referring to maintainability? I've used some relatively complex json structures to store all sorts of stuff and I've never really had any issues. Searching json fields can be a bit tedious at times but that's just an inconvenience.
Hey Morgan,

I haven't had a chance to play with this yet, but I'll be needing to for a project here soon. What I had bookmarked to come back to when I started was https://coderwall.com/p/ov8eha/render-an-html-partial-inside-a-json-request

Here, mbillard suggests this approach:

# execute a block with a different format (ex: an html partial while in an ajax request)
def with_format(format, &block)
  old_formats = formats
  self.formats = [format]
  self.formats = old_formats

def controller_action
  with_format :html do
    @html_content = render_to_string :partial => 'path/to/view', :locals => { /* any locals needed in the view */ }
  render :json => { :html_content => @html_content }

Hope it can be of some help!
Excellent, glad you were able to get it figured out!
Oh,  and on your clone method, you need to call save:

def clone
  @project = Project.find(params[:id]).amoeba_dup.save
  render 'new'

That's probably your real issue - I just pulled up one of my projects where I used amoeba and noticed I had to call save on it. Sorry, I should have done that first =\
Also, do you have any validations on your Project or Task model not included in the snippets? 
Hey shesso, 

At first glance, it looks like you need to add the association to your amoeba block:

amoeba do
  include_association :tasks
  prepend :title => "Copy of "

With this done, re-try your 3rd attempt

Posted in New server failed provisioning

Hey Felender, 

How many droplets do you currently have on your account? DO has droplet limits - login to your DO account then go to your settings. You'll see in your profile info the current limit for your account. Depending on the age of your account, you may be able to request more just by clicking the link that shows your current limit.
Awesome! Good to know about the cron jobs, and great to hear that it seems to be a pretty simple fix!

I look forward to the "good news" update, fingers crossed! :)
Hmm, it's odd that the cron job is failing, yet manually running it is succeeding.

If you execute `env` from the linux console, do you have an entry for your database username in there? It would be whatever you have the name for the environment variable in your database.yml file.

If it is in there, then manually add it to your cron with:

crontab -e
export ENV_VAR_DB_USERNAME='the_username_from_env'
# replace ENV_VAR_DB_USERNAME with whatever the env var is from the database.yml file

# rest of your cron stuff

There might be a better way of getting this working - I can't help but feel we're on the verge of using brute force to get this thing to work... it may be worth shooting Chris an email over @hatchbox.io to get your cron working right with a rolling db username. Unfortunately I haven't got a chance to mess with hatchbox yet so I'm just not sure the extent of what's going on there to be able to come up with a friendly solution with your complete setup.

Check out the following page for the whole 2777 then 0777 bit... https://major.io/2007/02/13/chmod-and-the-mysterious-first-octet

Can you post your updated crontab? Does it still call -production or RAILS_ENV=production?

And can you manually run the rake task or does it give you the error there as well? How about: 

rake bien RAILS_ENV=production
There has to be something wrong with the permissions or the way your cron is being executed. I just did a quick test where I created a new user foo on a droplet, created a directory and put a txt file with "hello world" in there and symlinked it to my rails root directory. Then I assigned my deploy user to the foo group and created a simple rake task to read the contents of the text file that was symlinked to the rails root directory. Everything worked as expected.

I've had issues with cron jobs when using a runner so I only use tasks now which took care of everything. Would you mind trying this out:

rails root/lib/tasks/bien.rake
task bien: :environment do
  Bien.cron # I'm assuming this is the model/method you're trying to execute, correct?

You can then run it by just executing rake bien from your terminal like you do rake db:migrate...

If that works, you can add it to your schedule as:

every 1.day, at: '06:25 pm' do
  rake "bien"

Be sure to double check all the permissions and  group assignments, especially since you've done so much up to this point something may not have stuck.
Totally correct jaems, but 777 is an excellent way to tell if it's a permission issue you're dealing with, which based on what LinaeAzn said, was all they were after (at least that's how I interpreted it).
As long as the user that your app uses is a member of the same group the original files were assigned and that group has read access to the file then there's nothing more you should have to do. 

So it sounds like you need to add your deploy user to the group that the FTP user is a member of and then ensure the file and directory have the proper read access for the assigned group. For this, you may consider making a special group that you assign both your deploy user and your FTP user to. Then create the directory in the FTP users home dir and ensure the folder is assigned to the new group with read access for the group, and read/write access to the FTP user.

Can you post the cron job that whenever generated for you? Just do crontab -e to list them

How are you calling your script from the cron itself? Are you using a rake task? I had a similar issue relatively recently with a temp log file not being able to write to the tmp directory... I'll have to dig through it to see if I can recall what the fix was. I think it had to do with the way I was calling it from the rails console instead of a rake task - but I may be confusing that with something else entirely.

I'm not familiar with Hatch, so maybe Chris will see this and can chime in with how to handle the rolling releases. Maybe you can set an environment variable on deploy with the release version which you could use to rebuild the symlinks? That feels kinda awkward though...

Posted in Best way to create a belongs_to object from a has_many

Can a listing exist without a user? If so then you'll want to add the optional: true to the has_one :user on the listing model then you should be able to create it without any problems.

#columns: user_id
class Listing < ApplicationRecord
  belongs_to :user, optional: true
  has_one :site
  has_many :association_groups
  has_many :users, through: :association_groups

listing = Listing.create
listing_site = listing.build_site.save

And thanks for the offer, but no need! Answering questions helps me learn more and I enjoy the challenge! :)

Posted in Best way to create a belongs_to object from a has_many

Well, considering a site now can be created for a user or a listing, I believe you're going to have to set the slug manually or potentially put a "type" like field on the site table so your slug generator can check which type of site it is then set the slug based on that.

So for instance:

def slug_candidates
  if self.user_site?
      [user.first_name, user.last_name,],
      [user.first_name, user.last_name, :id]
  else # listing site

This way you can kind of control how the slug gets created based on whatever criteria you want

Posted in Condition if devise action view

Hey Jacob (hah),

The current controller and action are in the params. So in your view, you can do something like:

<% unless params[:controller] == "devise/sessions" && params[:action] == "new" %>
  <!-- show the menu -->
<% end %>

Chris just beat me to the post - so I'll just add that Chris' answer is much better if you just want it applied to all devise controllers - much more concise if you don't need to differentiate between actions.
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.