How can I get content from website using httparty? - ruby-on-rails

I want to grab content from a website, that I input into a submit form, and store that info as a json I can save to my db. I am trying to use HTTParty, but I'm not quite sure how to implement it to grab the data. Here is what I have so far.
controller
class UrlsController < ApplicationController
before_action :set_url, only: [:show, :edit, :update, :destroy]
#require "addressable/uri"
#Addressable::URI.parse(url)
# GET /urls
# GET /urls.json
def index
#urls = Url.all
end
# GET /urls/1
# GET /urls/1.json
def show
end
# GET /urls/new
def new
#url = Url.new
end
# GET /urls/1/edit
def edit
end
def uri?(string)
uri = URI.parse(string)
%w( http https ).include?(uri.scheme)
rescue URI::BadURIError
false
rescue URI::InvalidURIError
false
end
# POST /urls
# POST /urls.json
def create
#url = Url.new(url_params)
#app_url = params[:url]
respond_to do |format|
if #url.save
format.html { redirect_to #url, notice: 'Url was successfully created.' }
format.json { render action: 'show', status: :created, location: #url }
wordcount
else
format.html { render action: 'new' }
format.json { render json: #url.errors, status: :unprocessable_entity }
end
end
end
def wordcount
# Choose the URL to visit
#app_url = #url
#words = HTTParty.get(#app_url)
# Trick to pretty print headers
#wordcount = Hash[*#words]
end
# PATCH/PUT /urls/1
# PATCH/PUT /urls/1.json
def update
respond_to do |format|
if #url.update(url_params)
format.html { redirect_to #url, notice: 'Url was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #url.errors, status: :unprocessable_entity }
end
end
end
# DELETE /urls/1
# DELETE /urls/1.json
def destroy
#url.destroy
respond_to do |format|
format.html { redirect_to urls_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_url
#url = Url.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def url_params
params.require(:url).permit(:url)
end
end
That is my controller.rb. I am getting a 'bad argument (expected URI object or URI string)' from the line #words = HTTParty.get(#app_url) I need to change what url is put into the form to a valid URL, grab the content I want from that URL, and save that information.

Try something like this:
response = HTTParty.get('https://google.com')
puts response.body, response.code, response.message, response.headers.inspect
To answer your question you can implement the following method, make a new class or put it in a helper.
Might need to include HTTParty
def url_getter(url)
HTTParty.get(url)
end
and call it:
url_getter(#app_url)

Related

Is it possible to force download using URL? The file isn't in my Rails

I'm trying to create podcast pages.
I have mp3 file URL https://mcdn.podbean.com/mf/web/tcips9/Introverted.mp3
and want to have a download button linked to the mp3 file URL, so when I click it, I want to download instead of opening a new web browser and play.
= link_to "Download", #podcast.episode_audio_url, download: "{#podcast.episode_audio_url}"
I tried above code and it's opening a new web browser and play.
How do I achieve my goal? Please help,.
My controller
class PodcastsController < ApplicationController
before_action :set_podcast, only: [:show, :edit, :update, :destroy]
# GET /podcasts
# GET /podcasts.json
def index
#podcasts = Podcast.all
end
# GET /podcasts/1
# GET /podcasts/1.json
def show
end
# GET /podcasts/new
def new
#podcast = Podcast.new
end
# GET /podcasts/1/edit
def edit
end
# POST /podcasts
# POST /podcasts.json
def create
#podcast = Podcast.new(podcast_params)
respond_to do |format|
if #podcast.save
format.html { redirect_to #podcast, notice: 'Podcast was successfully created.' }
format.json { render :show, status: :created, location: #podcast }
else
format.html { render :new }
format.json { render json: #podcast.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /podcasts/1
# PATCH/PUT /podcasts/1.json
def update
respond_to do |format|
if #podcast.update(podcast_params)
format.html { redirect_to #podcast, notice: 'Podcast was successfully updated.' }
format.json { render :show, status: :ok, location: #podcast }
else
format.html { render :edit }
format.json { render json: #podcast.errors, status: :unprocessable_entity }
end
end
end
# DELETE /podcasts/1
# DELETE /podcasts/1.json
def destroy
#podcast.destroy
respond_to do |format|
format.html { redirect_to podcasts_url, notice: 'Podcast was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_podcast
#podcast = Podcast.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def podcast_params
params.require(:podcast).permit(:episode_url, :episode_title, :episode_description, :episode_audio_url, :episode_number)
end
end
Thank you in advance.
I would suggest you writing the download logic in a app controller. So in your routes you would have
get download_podcast, to: "downloads#podcast"
your controller would be
class DownloadsController
def podcast
send_file Podcast.find(params[:podcast_id]).episode_audio_url, type: "audio/mp3"
end
end
and your view would link to this action with
link_to "Download", download_podcast_path(podcast_id: #podcast.id), target: "_blank"

Rails 5.1 Trying to pass an attribute to a form using a link

I am trying to pass an attribute to an object that is being created by a link. I am on the show view of another object and I want to have two links available one that will make the :attribute false and the other to make the :attribute true. I have it set up so the default value of the this attribute is false and I tried using something like below, but it just saves it as nil in the database:
<%= link_to "Yes", new_building_listing_appointment_rented_unit_path(#building, #listing, #appointment, #rented_unit, leased: true) %>>
controller
class RentedUnitsController < ApplicationController
before_action :building
before_action :listing
before_action :appointment
before_action :set_rented_unit, only: [:show, :edit, :update, :destroy]
# GET /rented_units
# GET /rented_units.json
def index
#rented_units = appointment.rented_units
end
# GET /rented_units/1
# GET /rented_units/1.json
def show
end
# GET /rented_units/new
def new
#rented_unit = appointment.rented_units.new
end
# GET /rented_units/1/edit
def edit
end
# POST /rented_units
# POST /rented_units.json
def create
#rented_unit = appointment.rented_units.new(rented_unit_params)
respond_to do |format|
if #rented_unit.save
format.html { redirect_to [building, listing, appointment, #rented_unit], notice: 'Rented unit was successfully created.' }
format.json { render :show, status: :created, location: #rented_unit }
else
format.html { render :new }
format.json { render json: #rented_unit.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /rented_units/1
# PATCH/PUT /rented_units/1.json
def update
respond_to do |format|
if #rented_unit.update(rented_unit_params)
format.html { redirect_to [building, listing, appointment, #rented_unit], notice: 'Rented unit was successfully updated.' }
format.json { render :show, status: :ok, location: #rented_unit }
else
format.html { render :edit }
format.json { render json: #rented_unit.errors, status: :unprocessable_entity }
end
end
end
# DELETE /rented_units/1
# DELETE /rented_units/1.json
def destroy
#rented_unit.destroy
respond_to do |format|
format.html { redirect_to building_listing_appointment_rented_units_path(#building, #listing, #appointment), notice: 'Rented unit was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_rented_unit
#rented_unit = appointment.rented_units.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def rented_unit_params
params.require(:rented_unit).permit(:unit_no, :unit_model, :price, :bedrooms, :bathrooms, :half_baths, :square_footage, :leased, :appointment_id)
end
def building
#building ||= Building.find(params[:building_id])
end
def listing
#listing ||= Listing.find(params[:listing_id])
end
def appointment
#appointment ||= Appointment.find(params[:appointment_id])
end
end
From what I understand you are looking to populate leased attribute auto when you open a new from from the link.
You need to give the param param to the link.
<%= link_to "Yes", new_building_listing_appointment_rented_unit_path(#building, #listing, #appointment, #rented_unit, rented_unit: { leased: true } ) %>>
In the controller then you can do some thing like
# GET /rented_units/new
def new
#rented_unit = appointment.rented_units.new(rented_unit_params)
end
Then, in the new form you will see the checkbox (or other control) selected.

Controller Name Error

I have added a module to my application called Tokened.rb and added the include Tokened to my model. However, now when I try to load that model, I get a "NameError in TestingsController#index" error... I haven't included Tokened in my TestingsController, but not sure why I should or where I should put it.
My code:
testing.rb
class Testing < ActiveRecord::Base
include Tokened
end
My Tokened.rb module:
module Tokened
extend ActiveSupport::Concern
included do
after_initialize do
self.token = generate_token if self.token.blank?
end
end
private
def generate_token
loop do
key = SecureRandom.base64(15).tr('+/=lIO0', 'pqrsxyz')
break key unless self.class.find_by(token: key)
end
end
end
Finally, my testing controller:
class TestingsController < ApplicationController
before_action :set_testing, only: [:show, :edit, :update, :destroy]
# GET /testings
# GET /testings.json
def index
#testings = Testing.all
end
# GET /testings/1
# GET /testings/1.json
def show
end
# GET /testings/new
def new
#testing = Testing.new
end
# GET /testings/1/edit
def edit
end
# POST /testings
# POST /testings.json
def create
#testing = Testing.new(testing_params)
respond_to do |format|
if #testing.save
format.html { redirect_to #testing, notice: 'Testing was successfully created.' }
format.json { render :show, status: :created, location: #testing }
else
format.html { render :new }
format.json { render json: #testing.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /testings/1
# PATCH/PUT /testings/1.json
def update
respond_to do |format|
if #testing.update(testing_params)
format.html { redirect_to #testing, notice: 'Testing was successfully updated.' }
format.json { render :show, status: :ok, location: #testing }
else
format.html { render :edit }
format.json { render json: #testing.errors, status: :unprocessable_entity }
end
end
end
# DELETE /testings/1
# DELETE /testings/1.json
def destroy
#testing.destroy
respond_to do |format|
format.html { redirect_to testings_url, notice: 'Testing was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_testing
#testing = Testing.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def testing_params
params.require(:testing).permit(:name, :address, :signature)
end
end
What gives? I am not sure what is going on here and why it needs to be included in the controller.
First of all it should be lowercased: tokened.rb. But where is your file? It should be here modules/concerns/tokened.rb.

protect urls in rails

I have some pages in a rails website that can be accessed only by user and admin,
I am hiding them from the public inside the views with user_signed_in?.
the problem is that when you copy and paste the url of the page when not logged in
you can still access them.
I imagine its something I need to add in the controller of those pages.
Any help would be great as I am still learning rails.
for example i would like to protect this controller
class DailiesController < ApplicationController
before_filter :authenticate_admin!, except: [:index, :show]
before_action :set_daily, only: [:show, :edit, :update, :destroy]
# GET /dailies
# GET /dailies.json
def index
#dailies = Daily.order("created_at desc")
end
# GET /dailies/1
# GET /dailies/1.json
def show
end
# GET /dailies/new
def new
#daily = current_admin.dailies.new
end
# GET /dailies/1/edit
def edit
#daily = current_admin.dailies.find(params[:id])
end
# POST /dailies
# POST /dailies.json
def create
#daily = current_admin.dailies.new(daily_params)
respond_to do |format|
if #daily.save
format.html { redirect_to #daily, notice: 'Post was successfully created.' }
format.json { render action: 'show', status: :created, location: #daily }
else
format.html { render action: 'new' }
format.json { render json: #daily.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /dailies/1
# PATCH/PUT /dailies/1.json
def update
#daily = current_admin.dailies.find(params[:id])
respond_to do |format|
if #daily.update(daily_params)
format.html { redirect_to #daily, notice: 'daily was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #daily.errors, status: :unprocessable_entity }
end
end
end
# DELETE /dailies/1
# DELETE /dailies/1.json
def destroy
#daily = current_admin.dailies.find(params[:id])
#daily.destroy
respond_to do |format|
format.html { redirect_to dailies_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_daily
#daily = Daily.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def daily_params
params.require(:daily).permit(:description, :image)
end
end
have you already created a method called authenticate_admin?
you can try something like this
before_action :has_access?
def has_access?
redirect_to root_path unless user_signed_in? && current_user.admin?
end

Creation working locally, but not on Heroku. ActiveRecord::UnknownAttributeError (unknown attribute: user_id)

Users can create guides only when they're logged in.
When I click on the 'New Guide' link, this is what Heroku's log puts out:
2013-12-30T20:28:37.826032+00:00 app[web.1]: ActiveRecord::UnknownAttributeError (unknown attribute: user_id):
GuidesController:
class GuidesController < ApplicationController
before_action :set_guide, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
# GET /guides
# GET /guides.json
def index
if params[:tag]
#guides = Guide.tagged_with(params[:tag])
else
#guides = Guide.all
end
end
# GET /guides/1
# GET /guides/1.json
def show
end
# GET /guides/new
def new
#guide = current_user.guides.build(guide_params)
end
# GET /guides/1/edit
def edit
end
# POST /guides
# POST /guides.json
def create
#guide = current_user.guides.build(guide_params)
respond_to do |format|
if #guide.save
format.html { redirect_to #guide, notice: 'Guide was successfully created.' }
format.json { render action: 'show', status: :created, location: #guide }
else
format.html { render action: 'new' }
format.json { render json: #guide.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /guides/1
# PATCH/PUT /guides/1.json
def update
respond_to do |format|
if #guide.update(guide_params)
format.html { redirect_to #guide, notice: 'Guide was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #guide.errors, status: :unprocessable_entity }
end
end
end
# DELETE /guides/1
# DELETE /guides/1.json
def destroy
#guide.destroy
respond_to do |format|
format.html { redirect_to guides_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_guide
#guide = Guide.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def guide_params
params.require(:guide).permit(:title, :author, :description, :link, :tag_list) if params[:guide]
end
end
You have this in your new action
def new
#guide = current_user.guides.build(guide_params)
end
Why? The new action should just return the form to the browser to create a new guide. You repeat this in your create action, where it should be.
Also your index has this:
def index
if params[:tag]
#guides = Guide.tagged_with(params[:tag])
else
#guides = Guide.all
end
end
You should probably be using guide_params[:tag] since the :tag is being returned by the browser.
EDIT I see you are using [:tag_list] in your whitelist. I assume you are handing that somewhere else? Have you tested the ability to do an index action with a tag defined? I think the only place you want to use bare params[:xxxx] is in a private method.

Resources