问题
Ok so i have this data structure
class User < ActiveRecord::Base
has_many :companies, :through => :positions
has_many :positions
class Company < ActiveRecord::Base
has_many :positions
has_many :users, :through => :positions
class Position < ActiveRecord::Base
belongs_to :company
belongs_to :user
attr_accessible :company_id, :user_id, :regular_user
end
And my database structure
create_table "positions", :force => true do |t|
t.integer "company_id"
t.integer "user_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.boolean "regular_user", :default => true
end
And if i add another company to a users companies, the regular_user flag is always set to true
1.9.3-p125 :013 > @user.companies << Company.last
Company Load (0.3ms) SELECT `companies`.* FROM `companies`
ORDER BY `companies`.`id` DESC LIMIT 1
(0.0ms) BEGIN
SQL (0.2ms) INSERT INTO `positions`
(`company_id`, `created_at`, `regular_user`, `updated_at`, `user_id`)
VALUES
(263, '2012-07-25 13:56:56', 1, '2012-07-25 13:56:56', 757)
Is there a way to set the flag to false before the insert
I have been getting around it by doing this....which is hackish
@user.positions.update_all(:regular_user => false) if @user.is_admin?
Is there another way (cleaner) to achieve this
回答1:
Use a before_save
filter.
Ex.:
class Position
before_save :set_regular_user_to_false
def set_regular_user_to_false
self.regular_user = false
end
end
Like the filter name says, this will intercept the chain of events right before saving the position
object, so you can change the regular_user
attribute.
EDIT
def set_regular_user_to_false
if self.user.user_type != 'admin'
self.regular_user = false
end
true
end
回答2:
You can directly insert a position
user.positions << Position.new(company: Company.last, regular_user: false)
回答3:
Honestly its been a while since I've used AR migrations so double check my syntax before you run this on a production database.
Having said that, this is being set on a database level as your table structure has that set to true. So if a NULL situation exists it will be made true.
You should be able to run a migration that will change your database column to default to false. You can also override with a callback as @MurifoX suggests, but I think this better addresses your core complaint.
Good Luck!
class ChangePostitionsRegularUser < ActiveRecord::Migration
def up
change_column :positions, :regular_user, :boolean, :default => false
end
def down
change_column :positions, :regular_user, :boolean, :default => true
end
end
来源:https://stackoverflow.com/questions/11651489/is-there-a-way-to-stop-this-default-insert-in-rails