I'm building a Rails app in which one of the functions is that the user can write journal entries and save them. I'd like to remove every journal entry from the respective PostgreSQL table they're in. How do I do this?
# assuming your journal entries are a model named Entry
Entry.find(:all).each { |e| e.destroy! }
Probably not the most efficient way, but it will do what you ask.
If you don't care about callbacks and just want to delete everything in the table, you can use delete_all:
JournalEntry.delete_all
If you do want callbacks executed, you can use destroy_all:
JournalEntry.destroy_all
Related
i have Account Model,Asset, Capital and Revenue this table are all inherited in my Account model. i have 3 kind of attributes in my Account model. name, code and type. when i create an account where will be to insert will happen one in my account and the other one is in my type for example
Account.create(name: "test123", code:"test123", type:"Asset")
sql will run Two Insert one for Account model and one for Asset Table
and my sunspot work well it will reindex my database and i can search my params
but when i update my model Account my sql run one insert and one update
my question is how can i reindex my model when i update. with a particular data. i can do Sunspot.reindex but this is will load all data in my sql. that will cause me to slow
sql will run Two Insert one for Account model and one for Asset Table
FYI you use STI when you want to share same database table between multiple models because they are similar in attributes and behavior. Like AdminUser model is likely to have almost same attributes/columns as PublisherUser or ReaderUser. Therefore you might wish to have a common table called users or model User and share this table among the above mentioned models.
Point is: ActiveRecord will run a single SQL query not two, like:
INSERT INTO "accounts" ("name", "code", "type") VALUES ('test123', 'test123', 'Asset')
my question is how can i reindex my model when i update. with a particular data. i can do Sunspot.reindex but this is will load all data in my sql. that will cause me to slow
Actually sunspot_rails is designed to auto-reindex whenever you make changes to your model/record. It listens to the save callbacks.
But you need to make sure that you are not using methods like update_column(s). See the list of silent create/update methods which do not trigger callbacks and validations at all.
In addition, you need to understand the concept of batch size in terms of Solr. For performance reasons, all of your new indexes are not immediately committed. Committed means, writing indexes to database like in RDBMS commits.
By default the batch_size for commits is 50. Meaning after 50 index method executions only the indexes will be committed and you will be able to search the records. To change it, use following
# in config/initializers/sunspot_config.rb
Sunspot.config.indexing.default_batch_size = 1 # or any number
or
# in models; its not considered good though
after_commit do
Sunspot.commit
end
For manual re-indexing, you can use like #Kathryn suggested.
But, I don't think you need to intervene in the auto-operation. I think you were not seeing immediate results so you were worrying.
According to the documentation, objects will be indexed automatically if you are on Rails. But it also mentions you can reindex a class manually:
Account.reindex
Sunspot.commit
It also suggests using Sunspot.index on individual objects.
i put this to my model
after_update do
Sunspot.index Account.where(id: self.id)
end
I am trying to create a Rails app and I have a database consisting of author and a quotation by that author.
Now different users can choose to destroy or kill quotations from the database however it must only be deleted for that particular user i.e other users should still be able to see quotes that they didn't delete even if another user did.
I know that I would need to implement cookies but other than that I am unsure how to proceed. Can anyone point me to a tutorial or give me some pointers to get started on this complex task?
You surely have a User model in your application - one 'Rails-like' way to go about this would be to add a has_and_belongs_to_many relationship between User and Quotation.
This creates a relationship between each individual user and 'their' quotations. This relationship can be deleted without actually deleting a quotation, so all quotations would still be available to other users. If you want each user to be able to see all quotations by default, you would need to set up the relationship in advance.
Assuming you are using Devise to log your users in, all you'd need to do then is to replace Quotation.all with current_user.quotations in whichever controller you are using to display quotations.
The Rails guide linked above is quite helpful but basically you just need to add something like the following:
class User
has_and_belongs_to_many :quotations
before_create :add_quotations
def add_quotations
self.quotations << Quotation.all
end
#etc...
end
class Quotation
has_and_belongs_to_many :users
#etc...
end
and then run a migration adding a new table called users_quotations with the columns user_id and quotation_id.
EDIT
As #Yule pointed out this wouldn't let users see any quotations that were created after they were, and it would be quite annoying to have to set up the join tables in advance, so a more efficient way would be to have an excluded_quotations join table instead. So users can see all quotations except the ones that they have excluded.
I have a join table in rails that has a few entries that need to be deleted.
lets say the join table is named 'products_variants'
I found out i have a few entries in this join table that were created erroneously a while ago. I have their IDs, so i could go in phpmyadmin and delete them, but I want to make a migration to do it in case anyone uses an older database (which has happened before).
Since I don't have a ruby object representing this join table I cant do something like:
ProductsVariants.find(id_array)
How would i go about deleting these entries in a rails migration?
You can create AR class for this table inside of migration and use it for delete record.
How would you do it from the console? Whatever that is, put it in the migration. For example
class Cleanup < ActiveRecord::Migration
def up
execute("delete from product_variants where id in (1,2,3)")
end
def down
end
end
Barring a solution like maxd's answer, you can also delete them via plain 'ol SQL. If you already have the list of ids, you can do something like this:
ActiveRecord::Base.connection.execute("DELETE FROM products_variants WHERE id IN (...)")
Where ... is the list of ids to delete.
Semi-pointless side-note: Technically speaking, data manipulation is not typically done in the migrations for various reason; one of them being that you're usually not necessarily guaranteed that all (or even any) migrations will be run by your colleagues (speaking very generally here), or in the case of new local project setups (meaning, you've just pulled down the project code and are setting it up locally for the first time).
While it doesn't sound like this is an issue in your scenario, if you want to do this the Rails-y way, one alternative would be to put this in a Rake task, so that you or others can execute it as needed, rather than relying on the migrations.
i have an association for a user as user has_many agents and agent belongs_to user.
in rails console,i am trying to use different users to test a particular scenario and i want a user with no agents,hence i want to delete the user.agents.
i tried user.agents.map(&:destroy),but it gives error as ActiveRecord::StaleObjectError: Attempted to delete a stale object.i even tried user.agents.delete_all but it too does not work.can i delete the users agents with a single command in rails console.
You better use destroy because it goes through all the Rails magic (callbacks and such)
user.destroy #For a single record
user.agents.destroy_all #For a collection
You are looking for a .destroy_all method. It destroys all records of a given collection.
So user.agents.destroy_all, would return an empty array for user.agents.
You could not have used .delete_all because it is a class method and it deletes records that match a given condition. Like this, Agent.delete_all(condition). If used without a condition it deletes all records from a matched table.
Keep in mind that .destroy methods are instance methods. They instantiate an object and perform callbacks before erasing it. .delete methods are class methods and they directly erase an object.
This works for me
user.agents.find_each(&:destroy)
ActiveRecord::StaleObjectError
Is for Optimistic locking, remove any locks you have on it before trying to delete again. Check if anyone else is using the system or submit any forms you have open.
I am learning Rails and I am reading the Beginning Rails 3 book. When you have a has_many association you automatically receives methods.
Let say user has many articles.
user.articles.delete(article)
Now that line only set the foreign key of the article to "NULL". Is it correct that you also must destroy/delete the article if you want it to disappear from the database, or is there a method that does it both?
And what happens if you destroy an article that is in a relationship with a user before you delete the association?
There are some difference between delete and destroy.
The delete method essentially deletes a row.. that's it..
On the other hand, destroy allows you more options:
it will check any callbacks such as before_delete, or any dependencies specified on the model.
it will also keep the object that just got deleted in memory; So it allows you to leave a message saying for example: “Article #{article.id} deleted!!”
And the answer for your question: it will delete any child objects associated with the object.
So, instead of
user.articles.delete(article)
you can use
user.articles.destroy(article)
In this way you will prevent any orphaned rows on the database.