I am working on a rails app, and I added a table. On that table, I wanted an index so to add one, I made a migration for adding a unique index. My migration looks like
class AddIndexToTable < ActiveRecord::Migration
def change
add_index :table, :user_id, unique: true
end
end
everything seemed fine, but now when I run my specs against my migration changes I now get the error
ActiveRecord::RecordNotUnique:
PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_table_name_on_user_id"
DETAIL: Key (user_id)=(15) already exists.
: INSERT INTO "table_name" ("user_id", "day", "last_visited_on", "daily_rewards", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id"
I have tried dropping the DB's, re-migrating, re-setting the pk_sequence with ActiveRecord::Base.connection.reset_pk_sequence!(table_name) and other fixes I could find, but I am still stuck on the same error.
Could anyone help me understand why I keep getting this error, and how it can be fixed? I can post more code if needed
You've got either a factory or a test that's trying to create multiple table records for the same user. Either that's going to be obvious looking in the test that's causing this, or perhaps it's an integration test and you don't have your test environment set up properly to clean out the DB between test cases.
For me it was the error that was I allowing the id in the controller params and that I had and let! create ... run at every test. So it tried to create again with the same id.
Removing id from allowed params fixed it.
Related
So I replaced CKEditor with ActionText in my rails 6 application, the upgrade to rails 6 and installation of action text was smooth.
I want to ask how I can be able to migrate the data from my model attribute to the newly established action text association (well not exactly migrate, I want to be able to display the old data and even be able to edit/update it).
For example, I have a description attribute in my model that was used with CKEditor before, now I have changed that field to a rich_text field like this: has_rich_text :description
So now all references to description simply query its rich_text association.
If I wanted to do something like this in my view, how can I achieve that?
#model.description (display if rich_text data is present) || #model.description (or try this if rich_text data is blank, also display nothing if both is blank)
I'd like to achieve this for show, edit, update and delete actions. Any idea how to make this work?
Why not just migrate the Ckeditor columns to the the new action_text table?
class ConvertCkeditorToActionText < ActiveRecord::Migration[6.0]
def up
action_text_rich_text_statement = ActiveRecord::Base.connection.raw_connection.prepare('action_text_rich_text_statement', <<-SQL)
INSERT INTO action_text_rich_texts (
name, body, record_type, record_id, created_at, updated_at
) VALUES ($1, $2, $3, $4, $5, $6)
SQL
Rails.application.eager_load!
transaction do
Post.all.each do |post|
ActiveRecord::Base.connection.raw_connection.exec_prepared(
'action_text_rich_text_statement', [
'body',
post.body,
"Post",
post.id,
post.created_at,
post.updated_at
])
end
end
end
def down
raise ActiveRecord::IrreversibleMigration
end
end
I have an account_users table, which has account_id and user_id. So I added an index at the DB level for maintaining unique records
add_index :account_users, [:account_id, :user_id], unique: true
Sometimes I am getting this exception, even though I am sure that I am entering the right combination of account and user, I mean a record which is not present
And sometimes it magically works and sometimes I am getting the below error
"ActiveRecord::RecordNotUnique: PG::UniqueViolation: ERROR: duplicate key value violates unique constraint \"account_users_pkey\"\nDETAIL: Key (id)=(6) already exists.\n: INSERT INTO \"account_users\" (\"account_id\", \"user_id\", \"created_at\", \"updated_at\", \"common_role_id\", \"added_by_user_id\") VALUES ($1, $2, $3, $4, $5, $6) RETURNING \"id\"","duration":25.14,"view":0.0,"db":9.59}
I would like to know if unique: true is the culprit here.
Unique constraint restrict you to add any duplicate entry in your db table. So if you have already have any duplicate entry in your table then unique constraint will not be added.
You must first make them unique first.
I was following this railscast, and finished the tutorial. Everything was working fine. Then I decided to use hstore instead of a serialized hash, and after setting up hstore, ran into a error:
PG::Error: ERROR: Syntax error near '!' at position 4 : INSERT INTO "products" ("product_type_id", "created_at", "properties", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"
I googled, and found a similar SO question, but I'm using Rails 4, which supposedly doesn't need to use that gem anymore.
Here's my code:
The relevant portion of my form.html.haml looks like this
= f.fields_for :properties, OpenStruct.new(#product.properties) do |builder|
- #product.product_type.products.each do |product|
= render "products/fields/#{product.field_type}", field: field, f: builder
My Product model looks like this:
class Product < ActiveRecord::Base
belongs_to :product_type
serialize :properties
end
I can post more code if it will help. Thanks!
The Rails4 PostgreSQL driver for ActiveRecord is supposed to have native support for PostgreSQL's hstore type so you shouldn't need to use serialize at all. Try ditching the serialize.
BTW, a ! will appear in a YAML string when you attempt to serialize some objects to YAML:
"--- !ruby/object:SomeClassName ..."
and that ! could cause some problems if PostgreSQL was expecting to see an hstore string.
here is what I am trying to do: Find if anyone has tweeted about a specific course offered. If someone has indeed tweeted about it, I'd like to save that tweet to my Tweet Model and then display that tweet in the corresponding course page.
The scripts works locally by running rails runner get_tweets.rb but on Heroku it seems that the script gets executed but doesn't write to the database. In heroku I am running heroku run rails runner get_tweets.rb (using the Cedar stack).
def get_course_tweets
#courses = Course.all
#courses.each do |course|
url = course.url
tweets = Twitter.search(url, {:rpp => 100, :recent => true, :show_user => true})
tweets.each do |tweet_info|
unless Tweet.find_by_tweet_id(tweet_info.id).present?
tweet = Tweet.new
tweet.course_id = course.id
tweet.tweet_id = tweet_info.id
tweet.tweet_text = tweet_info.text
tweet.from_user = tweet_info.from_user
begin
tweet.save!
rescue => error
puts error
end
end
end
end
end
Edit:
The current error I get from rescue is the following:
PG::Error: ERROR: value "186306985577299969" is out of range for type integer : INSERT INTO "tweets" ("book_id", "course_id", "created_at", "from_user", "tutorial_id", "tweet_already_exists", "tweet_id", "tweet_posted_to_reviews", "tweet_text", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING "id"
As can be seen from your error
value "186306985577299969" is out of range for type integer
you need to use a different datatype (for tweet_id, I believe), presumably a BIGINT, which ranges from -9223372036854775808 to 9223372036854775807.
To do so in Rails you can pass :limit => 8 in your up migration:
change_column :tweets, :tweet_id, :integer, :limit => 8
Note that you should always do some sort of logging or reporting when you rescue, or else bugs like this become very difficult to track down because they silently get bypassed.
The Twitter API actually sends back two types of ID's for tweets and users etc., one is a number, where as the other is a string representation of the number. This is because it's a very real possibility that they will have so many tweets and users that the ID's can overflow in different implementations. If you use the String as your value when inserting it shouldn't happen anymore.
The field is called id_str
Question: How can I achieve the model design below using ActiveAdmin and Devise 2?
I have set up active_admin successfully with an existing User model for bootstrapping it.
I assumed this model design means ("Have adminusers manage users").
Here is my current model set up:
irb(main):003:0> User.column_names
=> ["id", "created_at", "updated_at", "avatar", "name"]
irb(main):004:0> AdminUser.column_names
=> ["id", "email", "encrypted_password", "reset_password_token", "reset_password_sent_at", "remember_created_at", "sign_in_count", "current_sign_in_at", "last_sign_in_at", "current_sign_in_ip", "last_sign_in_ip", "created_at", "updated_at"]
Now I would like to add some authenticaton for my User model. However I am unable to migrate the results of rails generate devise User without this conflict:
== AddDeviseToUsers: migrating ===============================================
-- change_table(:users)
-> 0.7201s
-- add_index(:users, :email, {:unique=>true})
rake aborted!
An error has occurred, this and all later migrations canceled:
PG::Error: ERROR: could not create unique index "index_users_on_email"
DETAIL: Key (email)=() is duplicated.
: CREATE UNIQUE INDEX "index_users_on_email" ON "users" ("email")
Tasks: TOP => db:migrate
Now I do not have an email attribute in my current User model, but AdminUser does. So when Devise tries to create the email attribute in User I suspect this is why I get this error. But why? They are in different models?
Any help e.g. experiences, posts or tutorials would be appreciated (as well as an answer)
NOTE I have tried the solution found on the Devise wiki and here, with no success on migration.
The problem is in the creation of the index. Since you are changing the table, I'm assuming you already have records in it - trying to add an email column and subsequently add a unique index on it will not work because the column won't have unique values yet. Devise adds an index on the email column because it is the primary login field - if you have a different field for login (say, username), then add the index on that instead. If you are planning to start using email for login, then remove the index for now and add it once you have populated the email column with unique values.