ActiveRecord::StatementInvalid (SQLite3::BusyException: database is locked - sql

I know this a duplicate question but i tried all other solutions did not work for me.
when I create new message it does not insert it in on first click and on the second click it insert the same message twice, if I look at the terminal after the first click i get
ActiveRecord::StatementInvalid (SQLite3::BusyException: database is locked: INSERT INTO "notifications" ("content", "user_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)):
ActiveRecord::StatementInvalid (SQLite3::BusyException: database is locked: commit transaction):
solutions I tried are
ActiveRecord::Base.connection.execute("BEGIN TRANSACTION; END;")
I got unknown file attribute: B.
bundle exec rake db:reset
it cleared all my data but I still got the same results.
default: &default
adapter: sqlite3
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
timeout: 10000
I tried to increase timeout but it did not work for me.
app/controllers/messages_controller.rb
class MessagesController < ApplicationController
before_action :authenticate_user!
before_action :set_conversation
def index
if current_user == #conversation.sender || current_user == #conversation.recipient
#other = current_user == #conversation.sender ? #conversation.recipient : #conversation.sender
#messages = #conversation.messages.order("created_at DESC")
else
redirect_to conversations_path, alert: "You don't have permission to view this."
end
end
def create
#message = #conversation.messages.new(message_params)
#messages = #conversation.messages.order("created_at DESC")
if #message.save
ActionCable.server.broadcast "conversation_#{#conversation.id}", message: render_message(#message)
redirect_to conversation_messages_path(#conversation)
end
end
private
def render_message(message)
self.render(partial: 'messages/message', locals: {message: message})
end
def set_conversation
#conversation = Conversation.find(params[:conversation_id])
end
def message_params
params.require(:message).permit(:context, :user_id)
end
end
This is an image from the terminal

Related

Clearance failure when forbidden password reset

I’m using clearance and love it, but I'm having trouble resetting passwords. I type in my email to reset the password, which works, but then when I try to navigate to the edit password page using the reset token, I get the failure when forbidden flash error “Please double check the URL or try submitting the form again” and it redirects me back. I get the same error in my tests.
I think this has something to do with my before_action statements, but I just don’t know how to fix them. I have researched questions like this to no avail.
I'm sure it's a stupid question, but I'm new so I really appreciate any help. Please let me know if this isn't enough code.
class UsersController < Clearance::UsersController
before_action :require_login, only: [:create] # does this need to be in both user controllers?
...
def user_params
params.require(:user)
end
end
And here is the clearance controller.
class Clearance::UsersController < ApplicationController
before_action :require_login, only: [:create]
require 'will_paginate/array'
def new
#user = user_from_params
render template: 'users/new'
end
def create
#user = user_from_params
#user.regenerate_password
if #user.save
sign_in #user unless current_user
UserMailer.welcome_email(#user).deliver!
redirect_to users_path
else
render template: 'users/new'
end
end
def edit
#user = User.friendly.find(params[:id])
end
def update
#user = User.friendly.find(params[:id])
if #user.update(permit_params)
redirect_to #user
flash[:success] = "This profile has been updated."
else
render 'edit'
end
end
private
def avoid_sign_in
redirect_to Clearance.configuration.redirect_url
end
def url_after_create(user)
dashboards_path(user)
end
def user_from_params
user_params = params[:user] || Hash.new
is_public = check_public_params(user_params)
first_name = user_params.delete(:first_name)
last_name = user_params.delete(:last_name)
email = user_params.delete(:email)
password = user_params.delete(:password)
parish = user_params.delete(:parish)
division = user_params.delete(:division)
admin = user_params.delete(:admin)
Clearance.configuration.user_model.new(user_params).tap do |user|
user.first_name = first_name
user.last_name = last_name
user.password = password
user.email = email
user.is_public = is_public
user.parish_id = parish.to_i
user.division = division
user.admin = admin
end
end
def permit_params
params.require(:user).permit(:first_name, :last_name, :email, :password, :is_public, :parish_id, :division, :admin)
end
end
EDIT: relevant portions of routes.rb
Rails.application.routes.draw do
resources :passwords, controller: "clearance/passwords", only: [:create, :new]
resource :session, controller: "clearance/sessions", only: [:create]
resources :users, controller: "clearance/users", only: [:create] do
resource :password,
controller: "clearance/passwords",
only: [:create, :edit, :update]
end
get "/sign_in" => "clearance/sessions#new", as: "sign_in"
delete "/sign_out" => "clearance/sessions#destroy", as: "sign_out"
get "/sign_up" => "clearance/users#new", as: "sign_up"
constraints Clearance::Constraints::SignedOut.new do
root to: 'high_voltage/pages#show', id: 'landing'
end
constraints Clearance::Constraints::SignedIn.new do
# root to: 'dashboards#index', as: :signed_in_root
root to: 'high_voltage/pages#show', id: 'parish_dashboard', as: :signed_in_root
end
# constraints Clearance::Constraints::SignedIn.new { |user| user.admin? } do
# root to: 'teams#index', as: :admin_root
# end
resources :users do
collection { post :import }
end
It turns out there was a conflict between the way I was finding the user instance in the password reset link. Clearance finds users simply by using #user, but since I'm using FriendlyId I needed to change that to #user.id.
So instead of...
<%= link_to 'Change My Password', edit_user_password_url(#user, token: #user.confirmation_token.html_safe) %>
I did
<%= link_to 'Change My Password', edit_user_password_url(#user.id, token: #user.confirmation_token.html_safe) %>
Thanks, Thoughbot, for this great gem!

testing create action with nested resources

I have a bit of a confusing rSpec issue - depending how I write my code, either the tests that describe the 'failing' specs fail or the tests that describe the 'successful' specs fail.
Here are the tests for the create action:
describe "POST 'create'" do
describe "failure" do
before(:each) do
#attr = {name: "", type_of_group: ""}
#student_attr = [{name: "Joe", gender: "Male"}, {name: "sally twotrees", gender: "Female"}]
#create = post :create, student_group: #attr, student: #student_attr
end
it "should have the right title" do
#create
response.should have_selector('title', :content => "Create a new group" )
end
it "should render the 'new' page" do
#create
response.should render_template('new')
end
it "should not create a user" do
lambda do
post :create, student_group: #attr
end.should_not change {#user.student_groups.count}
end
it "should flash an error message" do
#create
flash[:error].should =~ /please/i
end
end
describe "success" do
before(:each) do
#attr = FactoryGirl.attributes_for(:student_group)
# #student_attr = {name: "test", gender: "Male"}
end
it "should create a student_group" do
lambda do
post :create, student_group: #attr
end.should change {#user.student_groups.count}.by(1)
end
it "should create students" # do
# lambda do
# post :create, student_group: #attr, student: #student_attr
# end.should change {#student_groups.students.count}.by(1)
# end
it "should flash a success message" do
post :create, student_group: #attr
flash[:success].should =~ /has been added/i
end
it "should redirect" do
post :create, student_group_id: #group, student_group: #attr
response.should be_redirect
end
end
end
All of the 'failure' tests fail with this error:
Failure/Error: #create = post :create, student_group: #attr, student: #student_attr
ActionView::Template::Error:
`#student_group[students_attributes]' is not allowed as an instance variable name
if I write the code in my controller this way:
def create
#params = params[:student_group][:students_attributes]
#student_group = #user.student_groups.build(params[:student_group])
if #student_group.save
### RE: 'defensive coding' https://stackoverflow.com/questions/14502508/undefined-method-for-nilnilclass-when-pushing-values-to-an-array
if #params.present?
### https://stackoverflow.com/questions/11355820/rails-3-2-iterate-through-an-array
#params.each do |student|
#student_group.students.create(name:"#{student[:name]}", gender: "#{student[:gender]}")
end
end
# new subject path
redirect_to class_path(#student_group), flash: { success: "#{#student_group.name} has been added successfully" }
else
#title = "Create a new group"
flash.now[:error] = "Something's gone wrong. Please try again!"
render 'new'
end
end
and all of the 'success' tests fail if the controller code is written like this:
def create
#params = params[:student_group][:students_attributes]
#student_group = #user.student_groups.build(params[:student_group])
### http://railsforum.com/viewtopic.php?pid=40056#p40056
if #params.present?
#student = Student.new
else
#student = #student_group.students.build(#params)
end
if #student_group.save
### RE: 'defensive coding' https://stackoverflow.com/questions/14502508/undefined-method-for-nilnilclass-when-pushing-values-to-an-array
if #params.present?
### https://stackoverflow.com/questions/11355820/rails-3-2-iterate-through-an-array
#params.each do |student|
#student_group.students.create(name:"#{student[:name]}", gender: "#{student[:gender]}")
end
end
# new subject path
redirect_to class_path(#student_group), flash: { success: "#{#student_group.name} has been added successfully" }
else
#title = "Create a new group"
flash.now[:error] = "Something's gone wrong. Please try again!"
render 'new'
end
end
the form code is here: https://stackoverflow.com/a/17591802/2128691
from the above code it seems that your controller code is really messed up. In case of nested attributes, u just have to save the parent object. the child objects get saved automatically if they are valid. Also u dont need to assign the params the some instance object. they should be used directly. a simple example of nested attributes can be
User
has_many :comments
accepts_nested_attributes_for :comments
Comment
belongs_to :user
ur controller code should be as
def create
#user = User.new(params[:user])
if #user.save
flash[:notice] = 'success'
redirect_to some_path and return
end
render 'new'
end
the rspec controller test case can be as
it "should create a user with comments if valid data is provided" do
post :create, "user"=>{"name"=>"Prasad", "comments_attributes"=>{"0"=>{"comment"=>"first comment"}, "1"=>{"comment"=>"second comment"}}, "commit"=>"Save"
user = assigns[:user] #assigns lets u access the instance variable from the controller in the spec
user.should be_valid
user.comments.count.should == 2 #check that all the child models are saved
user.name.should == "Prasad"
user.comments.first.comment.should == 'first comment'
user.comments.last.comment.should == 'second comment'
response.should be_redirect(some_path) #since u redirected in the code
end
seriously, u need to go through rails guides.
I ended up using this code:
def create
#student_group = #user.student_groups.new(params[:student_group])
#params = params[:student_group][:students_attributes]
#student_group = #user.student_groups.build(params[:student_group])
if #student_group.save
### RE: 'defensive coding' http://stackoverflow.com/questions/14502508/undefined-method-for-nilnilclass-when-pushing-values-to-an-array
if #params.present?
### http://stackoverflow.com/questions/11355820/rails-3-2-iterate-through-an-array
#params.each do |student|
#student_group.students.create(name:"#{student[:name]}", gender: "#{student[:gender]}")
end
end
redirect_to new_student_group_subject_path(#student_group), flash: { success: "#{#student_group.name} has been added successfully. Next, add the subjects for this group" }
else
### http://railsforum.com/viewtopic.php?pid=40056#p40056
#student = #student_group.students.build
#title = "Create a new group"
flash.now[:error] = "Something's gone wrong. Please try again!"
render 'new'
end
end

"Expected css... to return something" : rspec fail while test by hand works (can't reproduce the fail myself)

I'm working on a training app which is an Ogame-Like game (https://github.com/arnlen/ogame-like).
I'm using rspec (with Capybara) in order to test my app.
I'm stacked for several hours because rspec is complaining for an error which *I can't reproduce * by myself with my browser.
Here is my rspec code :
describe 'Planet pages' do
let(:user){FactoryGirl.create(:user)}
before {sign_in user}
subject {page}
describe "new planet page" do
before {visit new_planet_path}
describe "with valid information" do
before do
visit new_planet_path
fill_in "Name", with: "MyPlanet"
click_button "Validate"
end
# This test doesn't pass
it {should have_selector('h1', text: "Planet")}
end
end
end
The failure :
1) Planet pages new planet page with valid information
Failure/Error: it {should have_selector('h1', text: "Planet")}
expected css "h1" with text "Planet" to return something
# ./spec/requests/planet_pages_spec.rb:34:in `block (4 levels) in <top (required)>'
Here is the involved code.
My function "sign_in" used by rspec (location : spec/support/utilities.rb)
def sign_in(user)
visit signin_path
fill_in "Email", with: user.email
fill_in "Password", with: user.password
click_button "Sign in"
end
My UsersController
class UsersController < ApplicationController
before_filter :signed_in_user, only: [:index, :show, :edit, :update, :destroy]
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
sign_in #user
redirect_to new_planet_path
else
render 'new'
end
[...]
My PlanetsController
class PlanetsController < ApplicationController
before_filter :signed_in_user
def index
#planets = current_user.planets
end
def new
#planet = Planet.new
end
def create
#planet = Planet.new(name: params[:planet][:name],
coordinates: generate_coordinates,
metal_ressource: 1000,
user_id: current_user.id)
if #planet.save
flash[:success] = "Welcome on your first planet!"
redirect_to action: 'index'
else
flash[:error] = "Error naming your planet"
render 'new'
end
end
end
And My Planet Index view
<% #planets.each do |planet| %>
<h1>Planet : <%= planet.name %></h1>
<p><%= "Coordinates : #{planet.coordinates}" %></p>
<% end %>
I tried to user the Capybara method "save_and_open_page", but rspec raised an error "undefined method"
I also tried step by step debugging by iterations on my spec file, and it revealed that the error occurs right after the "click_button 'Validate'". For an unknown reason, rspec seems not to be able to reach the planets_path ("index" action from PlanetsController).
I'm out, if anybody has an idea, I take it !
EDIT : SOLVED - Found the problem!
Using the "save_and_open_page" method from Capybara, I figured out what was going on: the planet created by rspec didn't have any coordinates, which was not allowed by the model.
How to debug with the wonderful "save_and_open_page" method
Add this to your gemfile : "gem 'launchy'"
Install it : bundle install
Put the command "save_and_open_page" wherever you want
Hope it could help. :)
Capybara also has a save_page method, which is easier to use as it does not seem to need the "launchy" gem. The pages are saved in tmp/capybara. In the rspec tests, be sure to use save_page inside before, it, or some other block. It will not work as a separate command. Example:
before { visit signup_path; save_page }

Need help Rspec test

I'm trying to learn RSpec and writing test for CRUD actions. Here is my controller:
class ArticlesController < ApplicationController
respond_to :html, :json
before_filter :authenticate_user!
# GET /articles
# GET /articles.json
def index
#articles = current_user.articles.all
respond_with(#articles)
end
# GET /articles/1
# GET /articles/1.json
def show
#article = current_user.articles.find(params[:id])
respond_with #article
end
# GET /articles/new
# GET /articles/new.json
def new
#article = current_user.articles.build
respond_with #article
end
# GET /articles/1/edit
def edit
#article = get_article(params[:id])
end
# POST /articles
# POST /articles.json
def create
#article = current_user.articles.build(params[:article])
flash[:notice] = "Article was successfully created!" if #article.save
respond_with(#article, location: articles_path)
end
# PUT /articles/1
# PUT /articles/1.json
def update
#article = get_article(params[:id])
if #article.update_attributes(params[:article])
flash[:notice] = "Article was successfully updated."
end
respond_with #article
end
# DELETE /articles/1
# DELETE /articles/1.json
def destroy
#article = get_article(params[:id])
#article.destroy
respond_with #article
end
private
def get_article(article_id)
current_user.articles.find(article_id)
end
end
And my articles rspec:
describe ArticlesController do
def valid_attributes
{
:title => "Introducting Node.js",
:content => "Node.js is an event-driven...."
}
end
let(:article) do
build(:article, valid_attributes)
end
describe "PUT 'update'" do
before(:each) do
controller.stub_chain(:current_user, :articles, :build) { article }
end
context "success" do
before(:each) do
article.should_receive(:update_attributes).and_return(true)
put :update, id: article.id
end
it "sets notice" do
flash[:notice].should eq("Article was successfully updated!")
end
end
end
describe "POST 'create'" do
before(:each) do
controller.stub_chain(:current_user, :articles, :build) { article }
end
context "success" do
before(:each) do
article.should_receive(:save).and_return(true)
post :create
end
it "sets notice" do
flash[:notice].should eq("Article was successfully created!")
end
it "should redirect to article path" do
response.should redirect_to(articles_path)
end
end
context "failure" do
before(:each) do
article.should_receive(:save).and_return(false).as_null_object
post :create
end
it "assigns #article" do
assigns(:article).should == article
end
end
end
end
My question is when I run rspec on PUT UPDATE test is failed. But POST test is passed. I don't have any idea what is going on. I'm using Rails 3.1.1 with omniauth. I'm not using Devise. Here is the test result. Why? Please help me guys?
Failures:
1) ArticlesController PUT 'update' success sets notice
Failure/Error: put :update, id: article.id
NoMethodError:
undefined method `find' for #<Object:0xa3cfd20>
# ./app/controllers/articles_controller.rb:61:in `get_article'
# ./app/controllers/articles_controller.rb:44:in `update'
# ./spec/controllers/articles_controller_spec.rb:46:in `block (4 levels) in <top (required)>'
Finished in 24.09 seconds
5 examples, 1 failure
Here's the thing.
When you're stubbing, you're just saying "if this method chain is called, return this." There are two issues with that. 1) the code doesn't ever call build, and 2) there's no actual associations.
I believe you'd need to stub current_user.articles to return an article collection. The problem is that AR associations aren't actual arrays, they're proxies.
See this SO post and this SO post for more details. A regular array won't treat the find method like the AR method it really is, and you're not returning a single article.
Since you have the article ID, you could just return that particular article, but your goal is to return that article from within the user's articles to avoid updating someone else's (I assume).
This SO post may also help, and this.
In other words, you may want a real user there, with real associated objects, so things like find will work w/o hackery.
(I fully recognize this isn't a real answer; I've never done this via stubbing, I've used factories/etc.)

Rails 3 Devise Update Password Without Logging Out

I'm Using Devise in my Rails 3.0.9 application for User Authentication. As I wanted to be able to manage Users, I created the following Users Controllers:
class UsersController < ApplicationController
def index
#users = User.all
end
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
flash[:notice] = "Successfully created User."
redirect_to users_path
else
render :action => 'new'
end
end
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
params[:user].delete(:password) if params[:user][:password].blank?
params[:user].delete(:password_confirmation) if params[:user][:password].blank? and params[:user][:password_confirmation].blank?
if #user.update_attributes(params[:user])
if current_user.update_with_password(params[:user])
sign_in(current_user, :bypass => true)
end
flash[:notice] = "Successfully updated User."
redirect_to users_path
else
render :action => 'edit'
end
end
def destroy
#user = User.find(params[:id])
if #user.destroy
flash[:notice] = "Successfully deleted User."
redirect_to users_path
end
end
end
I this works for showing, creating and deleting Users, but I have run into a problem when updating the passwords.
When I Update the password for the currently logged in account it automatically logs me out.
In the controller I tried to fix this using: (you can see it in the code above)
if current_user.update_with_password(params[:user])
sign_in(current_user, :bypass => true)
end
But that gives me this error ->
undefined method `update_with_password' for nil:NilClass
What I'm really looking for, is the ability to update any accounts password, without logging them out ( as admins have ability to change regular users password ).
It is not necessary to write
This code in the controller
if current_user.update_with_password(params[:user])
sign_in(current_user, :bypass => true)
end
Instead you should go ahead with below one
if #user.update_attributes(params[:user])
sign_in(current_user, :bypass => true)
redirect_to users_path
end
cheers :)
The easiest way to do this is call
sign_in(current_user, :bypass => true)
After the update.
This is what my controller action looks like:
def update_password
if current_user.update_with_password(params[:user])
sign_in(current_user, bypass: true)
flash[:notice] = "Updated Password Successfully"
else
flash[:error] = "There was an error updating your password, please try again."
end
end
I think this is basically what #challenge proposed but I just wanted to make a little cleaner and easier to understand.