Rails:违反外键约束

时间:2015-08-05 07:47:08

标签: ruby-on-rails ruby reference foreign-keys relational-database

我有三个模型:BookgenreBookGenre,这里是关系:

class BookGenre < ActiveRecord::Base
  belongs_to :book
  belongs_to :genre
end


class Book < ActiveRecord::Base
  has_many :book_genres
  has_many :genres, through: :book_genres
end


class Genre < ActiveRecord::Base
  has_many :book_genres
  has_many :books, through: :book_genres
end

然后我使用seed文件将数据放入这些表中。

但是当我想再次rake db:seed时,它会显示此错误

ActiveRecord::InvalidForeignKey: PG::ForeignKeyViolation: ERROR:  update or delete on table "books" violates foreign key constraint "fk_rails_4a117802d7" on table "book_genres"
DETAIL:  Key (id)=(10) is still referenced from table "book_genres".

在我的 seed.rb

Book.destroy_all
Genre.destroy_all
...create data 

2 个答案:

答案 0 :(得分:14)

dependent: :destroy定义中添加has_many选项。

Check docs

尊重数据完整性的更好选择是在数据库级别设置CASCADE DELETE:例如,您有comments表和users表。用户有很多注释您想要将一个foreign_key添加到表comments并设置删除注释,每当用户被销毁时,您将使用以下内容(on_delete: :cascade选项将确保它):

add_foreign_key(
  :comments,
  :users,
  column:
  :user_id,
  on_delete: :cascade
)

答案 1 :(得分:7)

试试这个:

08-05 09:52:45.082: D/BstCommandProcessor-Application(1928): Application crash has been observed. 
08-05 09:52:45.082: I/Process(9680): Sending signal. PID: 9680 SIG: 9
08-05 09:52:45.082: E/AndroidRuntime(9680): FATAL EXCEPTION: main
08-05 09:52:45.082: E/AndroidRuntime(9680): Process: com.example.vivzmultithreadingexample, PID: 9680
08-05 09:52:45.082: E/AndroidRuntime(9680): java.lang.IllegalStateException: Could not execute method of the activity
08-05 09:52:45.082: E/AndroidRuntime(9680):     at android.view.View$1.onClick(View.java:3828)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at android.view.View.performClick(View.java:4443)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at android.view.View$PerformClick.run(View.java:18433)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at android.os.Handler.handleCallback(Handler.java:733)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at android.os.Handler.dispatchMessage(Handler.java:95)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at android.os.Looper.loop(Looper.java:136)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at android.app.ActivityThread.main(ActivityThread.java:5021)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at java.lang.reflect.Method.invokeNative(Native Method)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at java.lang.reflect.Method.invoke(Method.java:515)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:827)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:643)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at dalvik.system.NativeStart.main(Native Method)
08-05 09:52:45.082: E/AndroidRuntime(9680): Caused by: java.lang.reflect.InvocationTargetException
08-05 09:52:45.082: E/AndroidRuntime(9680):     at java.lang.reflect.Method.invokeNative(Native Method)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at java.lang.reflect.Method.invoke(Method.java:515)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at android.view.View$1.onClick(View.java:3823)
08-05 09:52:45.082: E/AndroidRuntime(9680):     ... 11 more
08-05 09:52:45.082: E/AndroidRuntime(9680): Caused by: android.os.NetworkOnMainThreadException
08-05 09:52:45.082: E/AndroidRuntime(9680):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1145)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at java.net.InetAddress.getAllByName(InetAddress.java:214)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at com.android.okhttp.internal.Dns$1.getAllByName(Dns.java:28)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:216)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:122)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:292)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at com.android.okhttp.internal.http.HttpEngine.sendSocketRequest(HttpEngine.java:255)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:206)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:345)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:296)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:179)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at com.example.vivzmultithreadingexample.MainActivity.downloadImageUsingThread(MainActivity.java:68)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at com.example.vivzmultithreadingexample.MainActivity$DownloadImagesThread.run(MainActivity.java:108)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at java.lang.Thread.run(Thread.java:841)
08-05 09:52:45.082: E/AndroidRuntime(9680):     at com.example.vivzmultithreadingexample.MainActivity.downloadImage(MainActivity.java:48)
08-05 09:52:45.082: E/AndroidRuntime(9680):     ... 14 more