Jacob Montgomery

Joined

34,500 Experience
33 Lessons Completed
41 Questions Solved

Activity

Hi Linards,

I think what Jack is referring to is your comments controller create action:

class CommentsController < ApplicationController
  def create
    @comment = current_user.comments.build(comment_params)
  end
  private
  def comment_params
    params.require(:comment).permit(:content) #you're only allowing :content
  end
end

Your comment params are only permitting :content and in your new comment form you don't pass the blog ID either:

<% unless current_user.is_a? GuestUser %>
  <%= form_for @comment, url: '#' do |f| %>
    <div class="form-group">
      <%= f.label :content %>
      <%= f.text_area :content, class: 'form-control' %>
    </div>
    <%= f.submit 'Post Comment', class: 'btn btn-primary' %>
  <% end %>
<% end %>

And in your show action you're just creating a new comment without associating the @blog.id:

def show
   @blog = Blog.includes(:comments).friendly.find(params[:id])
   @comment = Comment.new # you should be building the comment from the blog
end

So what you should be able to do is something like:

def show
   @blog = Blog.includes(:comments).friendly.find(params[:id])
   @comment = @blog.comments.build
end

Which should now properly pass the :blog_id. You may have to play with this some, I haven't tested and I've only had one cup of coffee so my brains not firing on all cylinders yet but this should get you going in the right direction.

You could also do something like this (but the above is the more railsy way)

<% unless current_user.is_a? GuestUser %>
  <%= form_for @comment, url: '#' do |f| %>
    <div class="form-group">
      <%= f.label :content %>
      <%= f.text_area :content, class: 'form-control' %>
      <%= f.hidden_field :blog_id, @blog.id %>
    </div>
    <%= f.submit 'Post Comment', class: 'btn btn-primary' %>
  <% end %>
<% end %>

And then just add to your permitted params:

class CommentsController < ApplicationController
  def create
    @comment = current_user.comments.build(comment_params)
  end
  private
  def comment_params
    params.require(:comment).permit(:content, :blog_id)
  end
end

Posted in Implementing Highcharts in RoR

Check out these resources:

http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/demo/chart-update/

http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/stock/demo/dynamic-update/

https://stackoverflow.com/questions/23830970/highcharts-trying-to-update-series

Based on the SO answer, you can either redraw the chart or just change out the series. I think changing the series would be the better way, but it would be worth testing them both and seeing what your experience is based on your needs.

Posted in Implementing Highcharts in RoR

I can't speak to the integration with filterrific, however loading live data is just a matter of making an ajax call and updating the data:

https://www.highcharts.com/docs/working-with-data/live-data

function requestData() {
    $.ajax({
        url: 'url_to_your_controller_action',
        success: function(point) {
            var series = chart.series[0],
                shift = series.data.length > 20; // shift if the series is 
                                                 // longer than 20

            // add the point
            chart.series[0].addPoint(point, true, shift);

            // call it again after one second
            setTimeout(requestData, 1000);    
        },
        cache: false
    });
}

In this example, they update every second, however you could remove that part and just have the ajax function trigger when a user updates the filter attributes. From here really all you need to do is update the ajax URL with whatever params you need in order to have your controller actions query return the correct set of records based on whatever filters you selected.

Posted in Implementing Highcharts in RoR

Hey John,

If you want to just get up and running, it's really just a matter of throwing a script tag in a page and load the resources... check out the first series below for some notes on how you can load your data in

From here, it just depends on what your needs are and how many charts you needs / how you need to load the data that would determine how you would really want to implement it all for your final product.

index.html.erb

<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/series-label.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>

<div id="container" style="height: 400px;"></div>

<script>
    Highcharts.chart('container', {

            title: {
                    text: 'Solar Employment Growth by Sector, 2010-2016'
            },

            subtitle: {
                    text: 'Source: thesolarfoundation.com'
            },

            yAxis: {
                    title: {
                            text: 'Number of Employees'
                    }
            },
            legend: {
                    layout: 'vertical',
                    align: 'right',
                    verticalAlign: 'middle'
            },

            plotOptions: {
                    series: {
                            label: {
                                    connectorAllowed: false
                            },
                            pointStart: 2010
                    }
            },

            series: [{
                    name: 'Installation',
                    data: [43934, 52503, 57177, 69658, 97031, 119931, 137133, 154175]
                    // here you could do <%= raw @your_data %>
                    // so in your controllers index action,  you'd have:
                    // @your_data = [43934, 52503, 57177, 69658, 97031, 119931, 137133, 154175]
                    // data: <%= raw @your_data %>
                    // would render data: [43934, 52503, 57177, 69658, 97031, 119931, 137133, 154175]
            }, {
                    name: 'Manufacturing',
                    data: [24916, 24064, 29742, 29851, 32490, 30282, 38121, 40434]
            }, {
                    name: 'Sales & Distribution',
                    data: [11744, 17722, 16005, 19771, 20185, 24377, 32147, 39387]
            }, {
                    name: 'Project Development',
                    data: [null, null, 7988, 12169, 15112, 22452, 34400, 34227]
            }, {
                    name: 'Other',
                    data: [12908, 5948, 8105, 11248, 8989, 11816, 18274, 18111]
            }],

            responsive: {
                    rules: [{
                            condition: {
                                    maxWidth: 500
                            },
                            chartOptions: {
                                    legend: {
                                            layout: 'horizontal',
                                            align: 'center',
                                            verticalAlign: 'bottom'
                                    }
                            }
                    }]
            }

    });
</script>

Posted in How to access a webpage and get its content

Hey Kelvin,

I've never done it, but the keyword you're looking for is "web scraping"

Check out: https://www.google.com/search?q=web+scraping

Posted in Create a User Profile after saving a Devise User

You could do something like this:

class User < ApplicationRecord
  has_one :profile
  after_create :init_profile

  def init_profile
    self.build_profile.save(validate: false)
  end
end

This lets you create the records but if you have other functions that check if profile.valid? then it would return false, and this may not be the desired result. See: https://www.dan-manges.com/blog/action-dependent-validations-and-why-on-update-is-bad Notice they're talking about the on: :update, which isn't what we're doing here, however the side effect is the same.

Posted in Rails Braintree couldn't update

What are you using to authenticate your users in this app if you're not using Devise? The error shown is clearly that it's expecting a password, and your validations on your user model also state you need password info when saving/updating a user.

I think you need to restructure your models some... your user model really needs to be focused on just the users information needed to login. Everything else needs to be in their own model that is associated with the user model.

So instead of putting a users company in the user model, create a company model and then depending on your needs, either do a has_one or has_many association between the user and company.

You also need a subscription model that will take care of keeping track of a users subscription. You may also consider a payment_source model that will keep track of the braintree_id.

Ideally, for what you're wanting to accomplish, you shouldn't need to save anything to the user model when you're creating a transaction.

Posted in Rails Braintree couldn't update

Hi Lee,

You probably have a validation on the user model or transaction model that's not being satisfied. Can you post any validations you have on your user and transaction model?

You can also use the byebug gem and place byebug right before the transaction that fails. Then try another subscription and this time when byebug is triggered, try creating the transaction there manually and see what error is raised.

Posted in How do I save a save a has_many association?

Hey Morgan,

Just iterate through the images and save each one like you would any has_many

def get_listings
  resp = client.get("/v1/some/api/posts")

  resp.body.each do |post|
    user = @user.posts.new(
      headline: post["headline"],
      body: post["body"]
    )

    listing["media"].each do |media|
      user.images.build(url: media["url"])
    end

    user.save
  end
end

I haven't tested this, so you may have to play around with it some (you may need to actually save the user first, then iterate through and build the associations, I can't recall off the top of my head) but you should get the idea.

Hey Dim,

Just check to see if the time field is blank

def example
  if boolean_field == true && datetime_field.blank?
      datetime_field = Time.now
  end
end

Posted in Chartkick and impressionist gem render not working

I can get the data to pass but not actually take into account the day, hour etc i.e. 20 impressions on Thurday and 40 impressions on Friday

If you work out what I gave you, it will do just what you're wanting... to where it will give you a range of impressions for your raffle based on a given time range.

the example provided is if the raffles were a seperate entity to the dashboard and not actually attached to anything

That doesn't matter at all for what you're trying to do.

It's not a diffult thing I'm trying to do here

Just because it's easy to explain doesn't necessariliy mean it's easy to do in code. I've done these exact kind of gigs plenty of times, so trust me, what I provided you will work. However, I can't do the project for you. I got you 3/4 of the way and gave you guidance to complete the other 1/4.

Best of luck.

Posted in Chartkick and impressionist gem render not working

Clone this - https://github.com/nanosplit/deleteme

bundle install
rake db:create
rake db:migrate
rake db:seed
rails s
http://lvh.me:3000

Take a look at the concern and controller:
https://github.com/nanosplit/deleteme/blob/master/app/models/concerns/raffle_impressions.rb
https://github.com/nanosplit/deleteme/blob/master/app/controllers/raffles_controller.rb

This isn't a copy/paste, you're going to have to take a look at what's actually happening, try to understand what is going on at each step, and then work out how to replicate the result in code. Google will be your best friend here. Most of the structure is there for you, you just have to figure out how to get your time ranges sorted out for the given time period you want to record, and then feed that into the raffle_impressions_count method.

Posted in Chartkick and impressionist gem render not working

Did you put raffle_impressions.rb in app/models/concerns/raffle_impressions.rb and restart your console / rails server?

Posted in Chartkick and impressionist gem render not working

Try this:

raffles.rb

class Dashboard::Raffle < ApplicationRecord
  is_impressionable :counter_cache => true, :column_name => :impressions_count, :unique => :all
  has_many :users
  include RaffleImpressions
end

app/models/concerns/raffle_impressions.rb

module RaffleImpressions
  extend ActiveSupport::Concern

  def raffle_impressions_count
    time_ranges = [['2017-12-08 08:00:00 -0600', '2017-12-08 09:00:00 -0600'], ['2017-12-08 09:00:00 -0600', '2017-12-08 10:00:00 -0600']]

    impressions = []

    time_ranges.each do |time|
      impressions << [[ time[0], time[1] ], self.impressionist_count(start_date: time[0], end_date: time[1]) ]
    end

    return { :name => self.name, :data => impressions }
  end
end

This is using concerns, so I had to add extend ActiveSupport::Concern to the raffle_impressions.rb. Testing the execution real quick I noticed I had the return hash wrong, I forgot to make name and data symbols... so be sure to update that in yours.

Also, to help you with debugging, be sure to watch Chris' video on it: https://gorails.com/episodes/debugging-with-better-errors

Posted in Chartkick and impressionist gem render not working

That's not how you setup a method to receive params

I would suggest some reading to get a better understanding

And really my example was only to illustrate the general concept you're after. So with your setup, you'd be looking for something more like:

raffle.rb

class Dashboard::Raffle < ApplicationRecord
  is_impressionable :counter_cache => true, :column_name => :impressions_count, :unique => :all
  has_many :users
  include 'RaffleImpressions'
end

raffle_impressions.rb

module RaffleImpressions
  def raffle_impressions_count
    time_ranges = [['2017-12-08 08:00:00 -0600', '2017-12-08 09:00:00 -0600'], ['2017-12-08 09:00:00 -0600', '2017-12-08 10:00:00 -0600']]

    impressions = []

    time_ranges.each do |time|
      impressions << [[ time[0], time[1] ], self.impressionist_count(start_date: time[0], end_date: time[1]) ]
    end

    return { name => self.title, data => impressions }
  end
end

Then you should be able to call Dashboard::Raffle.first.raffle_impressions_count to get an output for a single raffle. If you wanted multiple, you'd have to iterate over each Raffle, calling raffle_impressions_count on each iteration and load that into an array that you'd then pass to chartkick.

Posted in Chartkick and impressionist gem render not working

Oops, noticed a mistake - that's what I get for trying to write this out in a comment box :)

raffles = Dashboard::Raffle.all
time_ranges = [['2017-12-08 08:00:00 -0600', '2017-12-08 09:00:00 -0600'], ['2017-12-08 09:00:00 -0600', '2017-12-08 10:00:00 -0600']]

raffles_array = [] # don't need raffles_hash, instead just an array to load

raffles.each do |raffle|
  impressions = []
    time_ranges.each do |time|
        impressions << [[ time[0], time[1] ], raffle.impressionist_count(start_date: time[0], end_date: time[1]) ]
    end
  raffles_array << { name => raffle.name, data => impressions } 
end

return raffles_array

You may need to do some more playing but I think that's pretty close.

Posted in Chartkick and impressionist gem render not working

Yes, the last thing you see there is the return value - 0

So that's one value for one time range for one raffle. Now you need to create a function to build the hash like I showed so you end up with a range of time values along with their respective impression counts for each raffle.

So basically, what you're needing is something similar to:

edits made

raffles = Dashboard::Raffle.all

# time_ranges you need another function that you can give it a start_time and an end_time, 
# and then have it spit out an array like you see below that is an array of grouped time spans. 
# Example below shows two time groups that span one hour each.
time_ranges = [['2017-12-08 08:00:00 -0600', '2017-12-08 09:00:00 -0600'], ['2017-12-08 09:00:00 -0600', '2017-12-08 10:00:00 -0600']]

raffle_hash = {}

raffles.each do |raffle|
  impressions = []
    time_ranges.each do |time|
        impressions << [[ time[0], time[1] ], raffle.impressionist_count(start_date: time[0], end_date: time[1]) ]
    end
  raffle_hash[raffle.name] = impressions
end

return raffle_hash

This would give you an output like this:

[{name: "Test Raffle 2", data: [[['2017-12-08 08:00:00 -0600', '2017-12-08 09:00:00 -0600'], 34], [['2017-12-08 09:00:00 -0600', '2017-12-08 10:00:00 -0600'], 12]]}]

This is just an example of the basic steps you're going to have to take to get your output.

Posted in Chartkick and impressionist gem render not working

Right, because that's just a single query for a single point in time. Go into your rails console and type in your query and look at the output

Dashboard::Raffle.first.impressionist_count(start_date: Time.now - 1.hour, end_date: Time.now)

You'll see it only gives you a single value. So you have to make a function that will iterate over a range of time to eventually build up a hash that looks like this:

[{name: "Test Raffle 2", data: [["8am-9am", 34], ["9am-10am", 12], ["10am-11am", 45], ["11am-12pm", 89]]}]

Posted in Looking for advice on how to setup a relationship.

You bet! :)

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

© 2020 GoRails, LLC. All rights reserved.