In one of my programs I use a model called User and then use user = User.create(attr) where attr are the necessary attributes for this action. Then to destroy this I use user.destroy. However, I see that in the API Doc the destroy instance method for ActiveRecord::Base is deprecated -- is there a new/better way to go about destroying a model object?
It hasn't been deprecated, it's just been moved. The destroy method is now a member of ActiveRecord::Persistence instead of ActiveRecord::Base. However, you still call it the exact same way:
user.destroy
Related
I am new to mocking and stubbing, but I think I have a circumstance where their use would be ideal.
In my application, when a user saves a Product, an after_save callback fires that creates Publication instances which cause the product data to be sent to certain 3rd parties via API.
I have a request spec for Product that tests my CRUD operations.
If I stub either the API methods or mock the Publication model, will those mocks/stubs be used in my spec even though they are actually called in the Product after_save callback? I'm confused about this point.
Update
I figured I would just do it like this:
Publication.any_instance.stub(:publist).and_return(true)
And do that at the beginning of my test. That way whatever instance is created would be handled. Is that how it works?
Yes that stub will do what it says and the publist method on any instance of the publication class will always return true.
Instead of putting it "at the top" though do something like.
context 'when there is a publist' do
Publication.any_instance.stub(:publist).and_return(true)
it 'should ...' do
...
end
end
then if required you can do tests without the stub, or tests where publist returns false in other context blocks and be nice and clear in the spec.
I have a Log model which registers some actions done to a Foo model. That means, every time I create or update a Foo instance, I have to create a new Log instance for its table to register the corresponding action. Where does this creation belongs to? To Foo's model or to Foo's controller?
I was thinking, in the model I can use the before_save method and that would keep my controller skinny, but I'm not sure if it's right to put that logic there. Thanks
Logs can be used anywhere, it depends on your need to put them into right place.
For this case, your logging seems related to model changes but has little to do with HTTP requests, I think the better option would be model related place.
Option 1: after_save and after_update callback, not before_save. (You only want to log it after change already made effect)
Option 2: Model Observer.
I myself prefer Observer in this case because Log is not something inside this model so better not to use model callback. Also Observers allow you to add more things later easier. The downside is Observers are easy to be forgot, not a big deal if you can overcome it.
I know there is a lot of information available for passing variables between one controller action and another, both within the same controller and to other controllers.
But what I am trying to do, which I have been unable to find any documentation on, is temporarily store a variable in one controller action, so that it is available when another controller action(within the same controller) is called shortly after.
I tried using an instance variable but it didn't work.
I don't believe I can use flash because that is only for the very next action.
A class variable wouldn't be suitable because it would lead to conflicts if users were doing things simultaneously.
Any other ideas?
You likely want to use the session for this in your controller during first pass:
session[:save_me] = "for next time"
then on the next time in there
if( session[:save_me] )
#do cool stuff here
session[:save_me] = nil
end
Http is stateless so we use a session to pass information from request to request.
I want to block destroy and delete in the User model only and I want to block the callback. In few words I want to block any possibility to delete a user record. I tried by overriding destroy and delete methods but they are not called and the user is alway deleted.
class User < ActiveRecord::Base
def destroy
end
def delete
end
end
I do not want to use any gem related to this, so do not cite any gem. I am not sure if overriding those methods is a good idea, probably I should just create a 'deactivate' method and leave the default delete and destroy method there, just in case I will need them in the Rails console
Refer to Rails API Methods.
It's not necessarily a bad thing to override these methods provided you know what you're doing and the consequences. Sometimes it's the cleanest way to solve a problem.
My recommendation is looking at the following Rails API method documentation entries and ensuring you're not missing any important actions here.
#destroy
#destroy!
#delete
By creating those methods in your model, it will override anything in the inherited Rails API so it should work just fine.
I'm not sure that I understand your question fully.
One way to do this is to make the destroy and delete methods private.
You say that the methods never get called, but that the objects are being deleted anyway. How does this happen? Are you deleting them from a collection? You may need to override a class method of User rather than those two instance methods.
I am doing a check on a user model to determine whether s/he has one or more task_list, if she has more than one task_list only then she is allowed to delete it, otherwise an exception is thrown. I basically have an method called delete_list in the user model to allow for short hand deletions such as user1.delete_list(list1)
I am debating whether to put the check in CanCan where it would be apply as a before filter on the controller or whether to have it in the user model as well . What is the recommended practice?
I think a good DRY approach to this would be to create a method in your model that tests whether a delete is allowed. Then use that method from your controller or from ability.rb. IMHO I think having complicated permission/business logic decoupled from CanCan is better when there is a chance you might change to a different permission system in the future.
In your model:
def can_destroy_list(list)
... Do check here ....
end
In ability.rb
can :destroy, List do |list|
user.can_destroy_list(list)
end
Your controller and views can then also use can_destroy_list directly on the model instance if nessary or use: if can? :destroy, #list