I have a admin page on my site which allows me to load seeds by clicking a link.
it just calls:
Rails.application.load_seed
Problem is, there is no feedback that this is happening - I would like to see the seed output somehow on the page (the same as if ran in the command line).
Is there a way to do this when the link is clicked?
If you care about the page reloading, you could use jquery to do an ajax post request to a route, run the script (it doesn't need to be in the seed file--you could run it in the controller action you create) you're running to add data, and then in your success callback append the results.
If by 'output' you mean messages printed to standard output (e.g. using puts in the seeds file), you might grab the output in the controller using the code from this SO answer):
# controller:
#output = with_captured_stdout { Rails.application.load_seed }
But this will only display after the load finishes, you won't get any info during the process. If you require that, I think you'd need some streaming techniques.
Related
I'm having an issue with my specs. I'm trying to run a spec that creates and destroys an associated object, but none of my specs are creating or destroying that object. The weird thing is, I can literally copy and paste every line of code (except for the .should) out of each test into the console and the console will run each expectation perfectly, creating and destroying those objects. Here's a sample:
it "should not destroy notification for like on comment" do
comment = FactoryGirl.create(:comment)
like = FactoryGirl.create_list(:like, 2, likable: comment)
like.first.destroy
note = comment.user.notifications.find_by(notifiable: comment, from_comment: false)
note.should_not be_nil
end
Only the first like on a specific comment will send a notification to that comment's author. And if a comment only has one like, and that like is destroyed, it will destroy the notification it had originally sent, but it won't destroy the notification if the comment has more than 0 likes at any time.
Is the problem that I'm just not writing scalable code? I know my specs probably aren't perfect, but why is the console getting different results with identical input?
Are you running your rails console in test environment or in development as it defaults to?
Different database and environment configurations might be the reason for different behavior, also the note object might already exist in development db at the time you test it manually in console.
Either try running console in test environment:
$ rails c test
or better temporarily put debugger line inside your test code (you will need get 'debugger' gem installed if don't have it already):
it "should not destroy notification for like on comment" do
comment = FactoryGirl.create(:comment)
like = FactoryGirl.create_list(:like, 2, likable: comment)
debugger
like.first.destroy
note = comment.user.notifications.find_by(notifiable: comment, from_comment: false)
note.should_not be_nil
end
I have created nested form and want to test it from terminal. How can I Make POST request that creates 2 records - one for parent and one for child - at once?
Pry can help. This is not "testing" but more "debugging" in terminal.
gem 'pry'
bundle install
and in the beginning of your action accepting post request, let's say create;
def create
binding.pry
...
end
Browser will not respond but you will get what you want in your terminal.
See this railscast for more info.
HTTP-wise, nested forms are no different than regular forms. Rails uses the naming of the fields to separate parent data from child data. Use your browser's inspector to inspect the HTTP request sent when you fill out the form manually. From there, you can see the name of all the fields used. Then, in terminal, you can typically do something like this:
curl --data "parent[foo]=1&child[bar]=2" http://myapp.dev/parent/create
Just replace the parent[foo] and similar with what you find in the inspector, and it should all work. Tail the dev log if you want to see potential errors in the request.
How about to use rspec testing framework?
I have an app that I've converted over from another cms. The old URLs were being stored in the database like so:
/this-is-an-old-permalink/
And I need them to be like this:
this-is-an-old-permalink
Note the absence of forward slashes. What is the easiest way to go about removing them?
I'm not necessarily looking for the exact code to do it (although that'd be nice!) -- I'm asking also as a Rails newb: What is the best method to go about doing things like this? I've only really worked with Rails in setting up a model, controller, views and outputting data. I haven't had to do any processing like this. Would it go in the model? Any help is appreciated!
edit
Do I need to get all records, loop through them, do regex on that one field and then save it?
Since you're likely only going to write this once, your best bet is to create a script for it within lib, or to write a migration for it. I recommend the latter, because it will then be executed automatically with rake db:migrate if you restore from your old backup at a later date. You can then use all your standard Model processing tricks (like you would use on a Controller) within the migration without exposing the substitution code to a Controller.
EDIT:
You can add the following to a new file within lib/tasks to create a new rake task for this called db:substitute_slashes:
namespace :db do
desc "Remove slashes from old-style URLs"
task :substitute_slashes => :environment do
Modelname.find(:all).each do |obj|
obj.fieldname.gsub!(/regex here/,'')
obj.save!
end
end
end
The exclamation on the end of save! means it will throw an exception if the resulting object fails validation, which is a good thing to check for in this case.
You would then be able to execute this with the command rake db:substitute_slashes.
I have a Post Mode ,and a controller called happy_robot_controller,which will periodically crawl certain web sites , gather the data I am interested in , and then save to the Post Model.
skeleton of happy_robot_controller.rb:
craw the web site and get the interested data, save to title and content variables
#save to the Model
Post.new(:title=>title, :content=>content).save
Executing ruby happy_robot_controller.rb :
root#pierr-desktop:/work/web/yy/app/controllers# ruby happy_robot_controller.rb
happy_robot_controller.rb:54: uninitialized constant Post (NameError)
How should I be able to access the Post class? Should happy_robot_controller inherits ApplicationController like PostController do?
OR, should I put happy_robot in the models/post.rb?
It sounds like this "crawler" code should go into a rake task.
Start by creating the file RAILS_ROOT/lib/tasks/happy_robot.rake and put in the following:
namespace :happy_robot do
task :crawl => :environment do
# crawling code goes here
Post.new(:title=>title, :content=>content).save
end
end
You can then run this code by executing rake happy_robot:crawl from the command line (within your project directory of course).
Here is a nice rake tutorial: http://jasonseifer.com/2010/04/06/rake-tutorial
I've been trying to solve a problem for a few weeks now. I am running rspec tests for my Rails app, and they are working fine except for one error that I can't seem get my head around.
I am using MySQL with the InnoDB engine.
I have set config.use_transactional_fixtures = true in spec_helper.rb
I load my test fixtures manually with the command rake spec:db:fixtures:load.
The rspec test is being written for a BackgrounDRb worker, and it is testing that a record can have its state updated (through the state_machine gem).
Here is my problem:
I have a model called Listings. The rspec test calls the update_sold_items method within a file called listing_worker.rb.
This method calls listing.sell for a particular record, which sets the listing record's 'state' column to 'sold'.
So far, this is all working fine, but when the update_sold_items method finishes, my rspec test fails here:
listing = Listing.find_by_listing_id(listing_id)
listing.state.should == "sold"
expected: "sold",
got: "current" (using ==)
I've been trying to track down why the state change is not persisting, but am pretty much lost. Here is the result of some debugging code that I placed in the update_sold_items method during the test:
pp listing.state # => "current"
listing.sell!
listing.save!
pp listing.state # => "sold"
listing.reload
pp listing.state # => "current"
I cannot understand why it saves perfectly fine, but then reverts back to the original record whenever I call reload, or Listing.find etc.
Thanks for reading this, and please ask any questions if I haven't given enough information.
Thanks for your help,
Nathan B
P.S. I don't have a problem creating new records for other classes, and testing those records. It only seems to be a problem when I am updating records that already exist in the database.
I suspect, like nathan, transaction issues. Try putting a Listing.connection.execute("COMMIT") right before your first save call to break the transaction and see what changes. That will break you out of the transaction so any additional rollback calls will be non-effectual.
Additionally, by running a "COMMIT" command, you could pause the test with a debugger and inspect the database from another client to see what's going on.
The other hypothesis, if the transaction experimentation doesn't yield any results, is that perhaps your model really isn't saving to the database. Check your query logs. (Specifically find the update query).
These kind of issues really stink! Good luck!
If you want to investigate what you have in DB while running tests you might find this helpful...
I have a rspec test where I save #user.save and it works like a charm, but then I wanted to see if it's really saved in the DB.
I opened rails console for test environment
rails c test
ran
User.all
and as expected got nothing
I ran my spec that contains:
user_attr_hash = FactoryGirl.attributes_for(:user)
#user = User.new user_attr_hash
#user.save
binding.pry
I thought that stopping the test after save would mean that it's persisted, but that's not the case. It seems that COMMIT on the connection is fired later (I have no idea when:\ )
So, as #Tim Harper suggests, you have to fire that commit yourself in the pry console:
pry(#<RSpec::Core::ExampleGroup::Nested_1>)> User.connection.execute("COMMIT")
Now, if you run User.all in your rails console you should see it ;)