I would love to clean this code up:
def insert_general_methods
inject_into_file "app/controllers/application_controller.rb", after: "protect_from_forgery" do
a = "\n\n private\n\n def current_user\n"
b = " #current_user ||= User.find_by_auth_token!(cookies[:auth_token]) if cookies[:auth_token]\n"
c = " end\n"
d = "\n helper_method :current_user\n\n"
e = " def authorize\n"
f = " redirect_to login_url, alert: 'Not authorized. Please login.' if current_user.nil?\n"
g = " end\n"
a+b+c+d+e+f+g
end
end
Is there any method on Thor or Generator Module in Rails that allows me to inject this method in a more elegant form?
Use heredoc syntax:
inject_into_file 'app/controllers/application_controller.rb', after: "protect_from_forgery" do <<-RUBY
# some code
RUBY
end
Related
I'm trying to create a REST API using Phoenix with no Ecto or brunch.
What's the syntax for creating a post function in the router/controller with parameters, but not using Ecto?
For example in Ruby/Sinatra it would look something like this:
post "/v1/ipf" do
#weight1 = params[:weight1]
#weight2 = params[:weight2]
#weight3 = params[:weight3]
#weight4 = params[:weight4]
#goal1_percent = params[:goal1_percent]
#goal2_percent = params[:goal2_percent]
# etc...
end
Update
Based on Nick's answer, here's what I ended up with:
rest_api/web/router.ex:
defmodule RestApi.Router do
use RestApi.Web, :router
pipeline :api do
plug :accepts, ["json"]
end
scope "/", RestApi do
pipe_through :api
scope "/v1", V1, as: :v1 do
get "/ipf", IPFController, :ipf
end
end
end
rest_api/web/controllers/v1/ipf_controller.ex:
defmodule RestApi.V1.IPFController do
use RestApi.Web, :controller
import IPF
def ipf(conn, params) do
{weight1, _} = Integer.parse(params["weight1"])
{weight2, _} = Integer.parse(params["weight2"])
{weight3, _} = Integer.parse(params["weight3"])
{weight4, _} = Integer.parse(params["weight4"])
{goal1_percent, _} = Float.parse(params["goal1_percent"])
{goal2_percent, _} = Float.parse(params["goal2_percent"])
results = IPF.ipf(weight1, weight2, weight3, weight4, goal1_percent, goal2_percent)
render conn, results: results
end
end
rest_api/web/views/v1/ipf_view.ex:
defmodule RestApi.V1.IPFView do
use RestApi.Web, :view
def render("ipf.json", %{results: results}) do
results
end
end
Ecto and Brunch don't really have anything to do w/Phoenix handling a POST. Brunch is a web asset build tool, and Ecto is a database layer.
To add this new route, you just need to add an entry in the router for the new route:
post "/v1/spf", SPFController, :spf
And then create the controller:
defmodule MyModule.SPFController do
def spf(conn, params) do
# do whatever
end
end
That's it.
I have a helper_method that allows links to escape from a subdomain. However it is impacting my videos_controller, as it essentially seems to negate the 'current_event' method when not in the events controlller.
I've tried several dozen different ways over the last 4 days to make it so I can still escape my links from the subdomain, but still allow the videos_controller to work.
I think the best way to achieve this is to exclude the videos_controller from the helper method, but I'm not sure how (or if it is actually the best way forward - I'm obviously a noob!) Any suggestions please?! Relevant code below:
module UrlHelper
def url_for(options = nil)
if request.subdomain.present? and request.subdomain.downcase != 'www' and !options.nil? and options.is_a?(Hash) and options.has_key? :only_path and options[:only_path]
options[:only_path] = false
end
super
end
end
Videos_controller
def new
if current_event?
#video = current_event.videos.new
else
#video = Video.new
end
end
def create
if current_event.present?
#video = current_event.videos.new(params[:video])
#video.user_id = current_user.id
key = get_key_from_the_cloud
#video.key = key
else
#video = current_user.videos.new(params[:video])
#video.user_id = current_user.id
key = get_key_from_the_cloud
#video.key = key
end
if #video.save
flash[:success] = "Video uploaded!"
redirect_to root_url(subdomain: => current_event.name)
else
flash[:error] = "#{#video.errors.messages}"
render :new
end
end
current_event method
def current_event
if request.subdomain.present?
#event = Event.find_by_name(request.subdomain)
end
end
Did you take a look at this post yet?
You might want to create a new function test that only does something like
module UrlHelper
def test
puts "Test is called"
end
end
If that works you know its not including that fails but it has to be the method.
Otherwise you know the module is not included and you can narrow down the search.
I'm having the same issue mentioned here:
Multi-step form in Rails 3 with Paperclip attachments
"TypeError in..." "can't dump File"
However, I can't seem to wrap my head around the solution mentioned in the answer:
unless #model.valid?
#model.image.clear
#model.image.queued_for_write.clear
end
Where do I put the above lines?
Here's my code for my controller:
def new
session[:member_params] ||= {}
#member = Member.new(session[:member_params])
#member.current_step = session[:member_step]
end
def create
session[:member_params].deep_merge!(params[:member]) if params[:member]
#member = Member.new(session[:member_params])
#member.current_step = session[:member_step]
if #member.valid?
if params[:back_button]
#member.previous_step
elsif #member.last_step?
#member.save if #member.all_valid?
else
#member.next_step
end
session[:member_step] = #member.current_step
end
if #member.new_record?
render "new"
else
session[:member_step] = session[:member_params] = nil
flash[:notice] = "Personal Data Sheet saved!"
redirect_to #member
end
end
I tried putting it here after the declaration of #member, but no good:
session[:member_params].deep_merge!(params[:member]) if params[:member]
#member = Member.new(session[:member_params])
unless #member.valid?
#member.image.clear
#member.image.queued_for_write.clear
end
P.S.
I thought of appending my question to the question here:
Multi-step form in Rails 3 with Paperclip attachments
But I'm not sure if it's okay to post-follow-up questions on the same issue/question.
I have a ruby script that extracts information from a file (genbank) and I would like to load this data into the database. I have created the model and the schema and a connection script:
require 'active_record'
def establish_connection(db_location= "protein.db.sqlite3")
ActiveRecord::Base.establish_connection(
:adapter => "sqlite3",
:database => db_location,
:pool => 5,
:timeout => 5000
)
end
This is my script that outputs the data:
require 'rubygems'
require 'bio'
require 'snp_db_models'
establish_connection
snp_positions_file = File.open("snp_position.txt")
outfile = File.open("output.txt", "w")
genome_sequence = Bio::FlatFile.open(Bio::EMBL, "ref.embl").next_entry
snp_positions = Array.new
snp_positions_file.gets # header line
while line = snp_positions_file.gets
snp_details = line.chomp.split("\t")
snp_seq = snp_details[1]
snp_positions << snp_details[1].to_i
end
mean_snp_per_base = snp_positions.size/genome_sequence.sequence_length.to_f
puts "Mean snps per base: #{mean_snp_per_base}"
#outfile = File.open("/Volumes/DataRAID/Projects/GAS/fastq_files/bowtie_results/snp_annotation/genes_with_higher_snps.tsv", "w")
outfile.puts("CDS start\tCDS end\tStrand\tGene\tLocus_tag\tnote\tsnp_ID\ttranslation_seq\tProduct\tNo_of_snps_per_gene\tsnp_rate_vs_mean")
genome_sequence.features do |feature|
if feature.feature !~ /gene/i && feature.feature !~ /source/i
start_pos = feature.locations.locations.first.from
end_pos = feature.locations.locations.first.to
number_of_snps_in_gene = (snp_positions & (start_pos..end_pos).to_a).size # intersect finds number of times snp occurs within cds location
mean_snp_per_base_in_gene = number_of_snps_in_gene.to_f/(end_pos - start_pos)
outfile.print "#{start_pos}\t"
outfile.print "#{end_pos}\t"
if feature.locations.locations.first.strand == 1
outfile.print "forward\t"
else
outfile.print "reverse\t"
end
qualifiers = feature.to_hash
["gene", "locus_tag", "note", "snp_id", "translation", "product"].each do |qualifier|
if qualifiers.has_key?(qualifier) # if there is gene and product in the file
# puts "#{qualifier}: #{qualifiers[qualifier]}"
outfile.print "#{qualifiers[qualifier].join(",")}\t"
else
outfile.print " \t"
end
end
outfile.print "#{number_of_snps_in_gene}\t"
outfile.print "%.2f" % (mean_snp_per_base_in_gene/mean_snp_per_base)
outfile.puts
end
end
outfile.close
How can I load the data in outfile.txt into the database. Do I have to do something like marshall dump?
Thanks in advance
Mark
Your can write a rake task to do this. Save it in lib/tasks and give it a .rake extension.
desc "rake task to load data into db"
task :load_data_db => :environment do
...
end
Since the rails environment is loaded, you can access your Model directly as you would in any Rails model/controller. Of course, it'll connect to the database depending on the environment variable defined when you execute your rake task.
In a mere script, your models are unknown.
You have to define a minimum to use them as if in a Rails App. Simply declare them:
class Foo << ActiveRecord:Base
end
Otherwise, in a Rails context, use rake tasks which are aware of the Rails app details.
Im getting the following error:
undefined method `authorize_from_request'
Based on the documenation here: http://oauth.rubyforge.org/rdoc/classes/OAuth/Consumer.html
That method doesnt exist, but I saw this method used here:
http://teachmetocode.com/screencasts/oauth-with-the-twitter-gem/ and
so I'm guessing it was deprecated some time ago, but I can't seem to
find its replacement and was wondering what other way could I go about
solving this issue?
Thanks in Advance!
Controller Code:
class TwitterController < ApplicationController
def index
end
def login
oauth_request_token = oauth.get_request_token(:oauth_callback => "http://gnome.local/twitter/finalize")
session[:request_token] = oauth_request_token.token
session[:request_secret] = oauth_request_token.secret
redirect_url = oauth_request_token.authorize_url
redirect_url = "http://" + redirect_url unless redirect_url.match(/^http:\/\//)
redirect_to redirect_url
end
def finalize
oauth.authorize_from_request(session[:request_token], session[:request_secret], params[:oauth_verifier])
#client = Twitter::Client.new(oauth).verify_credentials
session[:request_token] = nil
session[:request_secret] = nil
oauth_access_token = oauth.get_access_token
#oauth_token = session[:oauth_token] = oauth_access_token.token
session[:oauth_secret] = oauth_access_token.secret
end
def client
oauth.authorize_from_access(session[:auth_token])
end
def oauth
#oauth ||= OAuth::Consumer.new(APP_CONFIG[:twitter][:consumer_key], APP_CONFIG[:twitter][:consumer_secret], :site => "http://api.twitter.com", :request_endpoint => "http://api.twitter.com", :sign_in => true);
end
end
(Original Post: http://groups.google.com/group/oauth-ruby/browse_thread/thread/614b27e4f5d80fab)
Got the same problem, the solution is to use according to the (old) Twitter gem:
request_token.get_access_token(oauth_verifier: params[:oauth_verifier])