Bat Cloud: A Rails Project
Tags: rails, ruby, webdev, beginners
Published: 2021-10-13 18:36:12

Today I finished my Ruby on Rails project which is my third final project for my Flatiron bootcamp. If you read my last blog, the concept of this project will be very familiar. I decided to redo my bat researchers’ log web application. With the power of Rails and learning new concepts, I knew I could make the original project even better. I did decide to rename the app Bat Cloud as it sounded better and a group of bats is sometimes called a cloud. If you didn’t read my last blog, I would recommend you do so, it is a quick read, and you can see the improvements. 

The main things I updated were a notes field, the associations, and a few new views and options. The note field update was partly to do with the fact that I had to have a many to many relationship. The associations between my models this time are as follows. Researchers have many notes, have many bats through notes, and have many discovered bats through a foreign key that associates a discovered bat to that researcher. Notes belong to a Researcher and a bat. Bats have many notes, have many researchers through notes, and belong to a discoverer (the researcher who created the bat entry). The new views include all researchers, and recently discovered bats which utilizes a scope method to sort the bats by date found. Another major improvement I made was adding a search field where a researcher can search by the bat tag number. I also implemented Omniauth so someone can log in via Google. I of course would like to add more features in the future, but I am happy with where this project is currently. 

I wanted to go over some of the challenges I faced with this project. I definitely struggled with my associations in the beginning and made things a lot more complicated than they needed to be. I originally wanted to have a separate model of an organization that would be the admin. After talking to my cohort lead, he said that he wouldn’t recommend going down that path at this point in time. Instead he suggested giving roles to certain researchers/users. This is what I ended up doing. Each researcher can either be an admin or a member. Any admin can change the access of any member. This of course isn’t the best method and I would like to improve this in the future. I originally tried to put an organization_id foreign key to associate a member with an organization but I realized that I really needed a separate model for organization to make this work. The other issue I faced with my associations was trying to have the bat belong to the researcher and the note, instead of having the note belong to the researcher and the bat. My cohort lead also brought up a good point about how many researchers could be taking notes on one bat. He also suggested having a foreign key that would associate a bat to the person who discovered the bat, which led to me adding the association of researchers having many discovered bats and a bat belonging to a discoverer through the discoverer_id that is a hidden field when you create a bat. Although I realized late in my project that my partial form for edit and new had the hidden field of discoverer_id so when someone edited a bat, they would become the discoverer. Also had to add a bunch of conditionals in case that researcher's account was deleted. I ended up figuring out my associations thanks to the help of my cohort lead. I am glad I talked things out with him before really starting to code. I see so many other students show up with bad associations and a finished project and having so many issues based on their associations. I wanted to make sure I took the time to nail those before getting too far.  

Another thing I really struggled with was converting all of my time stamps/datetime into something readable. Since I have so many fields that were time stamps/datetime, it seemed ridiculous to write out strftime methods for all of them. I did a bunch of googling and liked the solution from [stack overflow](https://stackoverflow.com/questions/22255476/rails-formatting-date) the best. The steps listed were: Create an initializer for it:
`config/initializers/time_formats.rb` 
Add something like this to it:
`Time::DATE_FORMATS[:custom_datetime] = "%d.%m.%Y"`
And then use it the following way:
`post.updated_at.to_s(:custom_datetime)`
The code I put in my `time_formats.rb` was `Time::DATE_FORMATS[:custom_datetime] = "%B %d, %Y at %I:%M %P"` 
In the show page: `@bat.updated_at.to_s(:custom_datetime)`. This worked out great and then when the researcher looks at a bat’s show page all the dates are read as “October 05, 2021 at 12:00 am.” which is more readable than the UTC. I also found out about the datetime_select field on form helpers. This made it a lot easier for someone to enter the date and time in a universal format that would be easy to put in the database without error. Before when people were testing my app, they would often enter something invalid by switching the date and month as the entry wasn’t intuitive before. I am not sure if this was the best solution to my dates problem but it does work. It isn’t as dry as I would like it to be. If anyone has a better solution, please let me know. 

While I have been enjoying this bootcamp, I will say that a part of this section that was really lacking was the section on OmniAuth. The two labs that dealt with it, didn’t have you do anything with the information you were given from the third party. It would check that you were able to sign in, but not how to process that information in your own database. I was left scratching my head on what to do with it. For instance, they didn’t mention anything about the uid. They also didn’t tell you how to deal with multiple third parties. Granted there are videos and plenty of information to find out about all this on your own, but I expected them to give a little more on this very important topic. Also a problem I have noticed when I sign in with a provider is that a lot of websites want you to enter a password to delete your account, and your provider password doesn’t work, so I am always at a loss of what to do in those situations. I ended up using Google as my provider for this project as it is how I like to sign in to most websites. I thought it was cool that Google, and Github offer icons for you to use as a developer! I liked that Github even had light and dark options. 

Here is my OmniAuth method:
```Ruby   
def omniauth
       @researcher = Researcher.find_or_create_by(email: auth[:info][:email]) do |r|
           r.email = auth[:info][:email]
           r.name = auth[:info][:name]
           r.uid = auth[:uid]
           r.provider = auth[:provider]
           r.password = SecureRandom.hex(16)
       end
 
       if @researcher.valid?
           session[:researcher_id] = @researcher.id
           redirect_to bats_path
       else
           flash[:danger] = "#{@researcher.errors.full_messages.join(", ")}"
           redirect_to login_path
       end      
   end
```

I do want to keep working on this app. In the future, I want to add password reset, a more secure admin function, the ability to edit and delete field notes, more static pages, and more styling. However it is more important to continue with my bootcamp than work on this project forever. Especially working full time again, I need to keep making progress so I can graduate from this bootcamp and fully switch into my new career path.