Home > Software engineering >  Can I have two different input fields and one column in the database?
Can I have two different input fields and one column in the database?

Time:02-11

I want to have two input fields, but only one column in the database. The first input is stored data in numbers and the other one is stored data in numbers divided by 24. You can put data only in one field. Is there any possible way to do this?

UPD: Migration:

def change
  add_column :employees, :hourly_payment , :integer
end

View: employees/_form.html.erb

<%= simple_form_for @employee do |form| %>
  <%= form.input :name %>
  <%= form.input :hourly_payment %>
  <%= form.input :monthly_payment %>
  <%= form.button :submit, class: "btn btn-success" %>
<% end %>

CodePudding user response:

Your model and database tables are the internals of your application and are not actually tied to the view by anything except how easy ActiveRecord makes it to use convention over configuration to link the two*.

In Rails style MVC the controller is responsible for passing user input to the model. Usually you would just do this with simple mass assignment:

class UsersController < ApplicationController
  def create
    @user = User.new(user_params)
    # ...
  end

  private 

  def user_params
    params.require(:user)
          .permit(:email, :salary)
  end
end

This is basically just passing a whitelisted hash of parameters straight to the model as is and it all gets passed to the setters that ActiveRecord magically created for you by reading the database schema.

But there is nothing stopping you from assigning attributes manually:

class UsersController < ApplicationController
  def create
    @user = User.new(user_params) do |user|
      user.salary = calculated_salary
    end
    # ...
  end

  private 

  def user_params
    params.require(:user)
          .permit(:email)
  end

  def calculated_salary
     if params[:user][:hourly_payment].present?
       params[:user][:hourly_payment]
     elsif params[:user][:monthly_payment].present?
       params[:user][:monthly_payment].to_i / 168
     else
        0 # sorry no cookies for you
     end
  end
end

Or monkeying with the parameters object:

def user_params
  params.require(:user)
        .permit(:email)
        .merge(salary: calculated_salary)
end

It is after all just a hash on steroids. The only thing that Rails will prevent you from is passing a parameters object that has not been whitelisted.

There is no stone tablet for what you can do in a controller. The only thing to bear in mind is that controllers are notoriously hard to test and fat controllers are a recipe for disaster.

If you're doing anything more complicated there are better solutions such as form objects, decorators or service objects.

CodePudding user response:

You'll need to create a view for that. Here is an example of migration:

def up
  sql = %(CREATE OR REPLACE VIEW my_view_models AS
  SELECT m.*,m.int_field*12 as my_new_value from my_models m
  )
  self.connection.execute(sql)
end

def down
  self.connection.execute('DROP VIEW IF EXISTS my_view_models')
end

Then, you can access your value with method my_new_value on your model. You'll need to change the name of the default table matching your model.

class MyModel
  self.table_name = 'my_view_models'
end

And access it via

MyModel.first.my_new_value

CodePudding user response:

Maybe you can serialize two number into a string, and stored a string in one column of database.

  • Related