9

I have the following helper method:

def parse_potential_followers(params)
  t_id = TestSet.where(:test_name => params[:test_set][:test_name]).pluck(:id)[0].to_i
  screen_names = params[:potential_followers].first[1].split("\n").reject(&:blank?)
  screen_names.each do |s|
    potential_follower = PotentialFollower.new(
      :screen_name => s,
      :test_sets_id => t_id,
      :status => 'new',
      :slug => generate_slug([t_id.to_s, s])
    )
    potential_follower.save
  end
end

The problem is that when I call this method, the test_sets_id is skipped when data is inserted in the table in the development environment, but not in the production environment. The three other attributes are saved fine.

All the attributes are defined in the potential_followers table.

I also have all the attributes in the potential_follower_params method in the potential_followers_controller.rb:

def potential_follower_params
  params.require(:potential_follower).permit(:screen_name, :test_sets_id, :connections, :status,
    :slug, :created_at, :updated_at)
end

test_sets_id is defined as an integer in the table. I even tried harcoding the value of t_id:

t_id = 12

But it still would not work in production.

Here's what's in the models/potential_follower.rb:

class PotentialFollower < ActiveRecord::Base
  belongs_to :TestSet
end

Here's the method in test_sets_contoller.rb:

def create
    @test_set = TestSet.new(test_set_params)
    respond_to do |format|
        if @test_set.save
            parse_potential_followers(params)
            format.html { redirect_to @test_set, notice: 'Test set was successfully created.' }
            format.json { render :show, status: :created, location: @test_set }
        else
            format.html { render :new }
            format.json { render json: @test_set.errors, status: :unprocessable_entity }
        end
    end
end

Any ideas?

EastsideDev
  • 6,257
  • 9
  • 59
  • 116
  • This may be a silly question, but are you sure that your production system has a record in `test_set` table with id of `12` or with the `test_name` that you are searching for? – Yevgeniy Goyfman Jan 07 '16 at 22:14
  • t_id is computed from the params, and this helper is executed is called after the params are saved to the test_sets table. See the test_sets_controller.rb method in the edits – EastsideDev Jan 07 '16 at 23:02
  • 1
    For having a deeper look into this, it would be helpful to have the code or some runnable relevant part of it that exhibits the problem published online somewhere (if this is possible). – tillmo Jan 14 '16 at 10:28

2 Answers2

1

Probably the production database does not have the field test_sets_id, but also in production mode, rails still creates the database record, while just ignoring the test_sets_id field of the hash. A rake db:migrate RAILS_ENV=production should solve the issue.

tillmo
  • 607
  • 5
  • 11
  • No, the field is there. In addition, if the field is not there, I would get an error. – EastsideDev Jan 11 '16 at 12:46
  • No, if the field were not there, you would not get an error. I have tried it. Just to be sure, have you tried executing `rake db:migrate RAILS_ENV=production`? – tillmo Jan 11 '16 at 15:23
  • 1) I've already told you that the field exists in the DB. I run phpmyadmin and I can see all the fields. 2) a missing field from the table will absolutely, positively produce a "something went wrong" because none of the views will work, 3) I have build script that calls rake:db migrate... and 4) I've already told you that the field is there – EastsideDev Jan 11 '16 at 19:47
  • Aha, I made the mistake of creating a separate hash and passing this to `new` (which is slightly different from what you do). Indeed, with such code, the strange behaviour that you are encountering could be explained with a missing field in the production DB. – tillmo Jan 12 '16 at 18:45
  • A missing field in the DB, if you try to use it in the app, will cause your views to fail. And once more, the field DOES exist in the production DB. – EastsideDev Jan 12 '16 at 23:02
1

You are straying from the Rails conventions. The belongs_to should be in snake case and singular, ie :

belongs_to :test_set

The database column should be singular as well. So the column should be renamed to test_set_id.

What a belongs_to :test_set declaration will do is that it will generate a test_set_id= (and a test_set= method too) on PotentialFollower. That is the convention for Rails. Once you have changed your belongs_to, it should now successfully save the value in development and production.

See http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-belongs_to

Thong Kuah
  • 3,263
  • 2
  • 19
  • 29
  • This did not fix the problem. I may have strayed from the rules, but it does not explain why Rails is doing it correctly in development mode but not in production. – EastsideDev Jan 11 '16 at 13:11
  • Hmm, so you fixed the code to follow Rails Conventions and it's still happening ? The biggest AFAIK between dev and prod is that prod loads all classes in the beginning - see `config.cache_classes` – Thong Kuah Jan 13 '16 at 08:11
  • Yes, but that just means that the code is not reloaded in between requests while in dev mode it is reloaded. That should not change the code behavior. I am also deleted the cache/assets and recompiling assets on production prior to every production deployment (and test on production). So, it's a clean build every time. – EastsideDev Jan 13 '16 at 11:30