#ruby-on-rails #ruby
#ruby-on-rails #ruby
Вопрос:
У меня есть таблица «местоположение» и таблица «роль»,
Таблица расположения:
id|location_name|location_code|category|
1 | location1 | 0001 | Urban |
2 | location2 | 0002 | Rural |
3 | location3 | 0003 |Suburban|
________________________________________
Таблица доходов:
id|role_code|rural|urban|suburban|
1 | 1001 | 5 | 10 | 15 |
2 | 1002 | 7 | 12 | 17 |
1 | 1003 | 9 | 14 | 19 |
__________________________________
Таблица местоположений предназначена для определения категории области (сельская, городская или пригородная), а таблица ролей предназначена для определения цены дохода на основе категории местоположения.
как мне соединить обе таблицы вместе, чтобы всякий раз, когда пользователи вводят местоположение и роль, они видели цену?
Ответ №1:
Текущая структура не очень масштабируема по своей природе. Я бы настоятельно рекомендовал изменить способ структурирования данных. Взгляните на следующий пример.
# Instead of storing the location category in as text you can store references
# of location_category in locations amp; revenues table
class LocationType # Location Category
end
# ---- -----------
# | id | name |
# ---- -----------
# | 1 | Urban |
# ---- -----------
# | 2 | Rural |
# ---- -----------
# | 3 | Sub Urban |
# ---- -----------
# Similarly instead of storing role_code, you can store references to roles
# in your revenue table
class Role
end
# ---- ------ --------
# | id | code | name |
# ---- ------ --------
# | 1 | 1001 | Role 1 |
# ---- ------ --------
# | 2 | 1002 | Role 2 |
# ---- ------ --------
# | 3 | 1003 | Role 3 |
# ---- ------ --------
class Location
belongs_to :location_type
end
# ---- ----------- --------- ------------------
# | id | name | code | location_type_id |
# ---- ----------- --------- ------------------
# | 1 | location1 | 001 | 1 |
# ---- ----------- --------- ------------------
# | 2 | location2 | 002 | 2 |
# ---- ----------- --------- ------------------
# | 3 | location3 | 003 | 3 |
# ---- ----------- --------- ------------------
class Revenue
belongs_to :location_type
belongs_to :role
end
# References for roles amp; location_type stored instead of actual values
# ---- ----------- --------- ------------------
# | id | role_id | revenue | location_type_id |
# ---- ----------- --------- ------------------
# | 1 | 1 | 5 | 2 |
# ---- ----------- --------- ------------------
# | 2 | 2 | 7 | 2 |
# ---- ----------- --------- ------------------
# | 3 | 3 | 9 | 2 |
# ---- ----------- --------- ------------------
# | 4 | 1 | 10 | 1 |
# ---- ----------- --------- ------------------
# | 5 | 2 | 12 | 1 |
# ---- ----------- --------- ------------------
# | 6 | 3 | 14 | 1 |
# ---- ----------- --------- ------------------
# | 7 | 1 | 15 | 3 |
# ---- ----------- --------- ------------------
# | 8 | 2 | 17 | 3 |
# ---- ----------- --------- ------------------
# | 9 | 3 | 19 | 3 |
# ---- ----------- --------- ------------------
С помощью этой структуры теперь вы можете запускать оптимальные запросы к вашей базе данных для извлечения данных.
# Example
location_type_id = params[:location_type_id]
role_id = params[:role_id]
@revenue = Revenue.where({
location_type_id: location_type_id,
role_id: role_id
}).sum(:revenue)
Если вы хотите, вы также можете включить location_id в свою таблицу доходов, тогда вы сможете найти доход для определенного местоположения следующим образом:
@revenue = Revenue.where({
role_id: role_id,
location_id: location_id
}).sum(:revenue)
Ответ №2:
Самый простой подход к этому — использовать if
инструкцию, чтобы проверить, является ли местоположение городским, сельским или пригородным.
Я предполагаю, что вы хотите использовать price в другой модели, поэтому я назвал модель transaction
в примере кода ниже.
if transaction_params[:price].blank?
if @transaction.location.category == 'Rural'
@transaction.price = @transaction.revenue.rural
elsif @transaction.location.category == 'Suburban'
@transaction.price = @transaction.revenue.suburban
else
@transaction.price = @transaction.revenue.urban
end
end
Вы можете сделать это с помощью create
метода в вашем контроллере транзакций.
Ответ №3:
Если пользователь вводит location2 и роль 1003, вы могли бы сделать:
location = params[:location] # or some other way to get the input
role = params[:role] # or some other way to get the input
location_category = Location.find_by(name: location).category.downcase
# now location_category will be rural
Reveneu.find_by(role_code: role).send(location_category)
# with the .send method you can access the column that you need(in this case rural)
Ответ №4:
Предполагая, что у пользователя есть role_code amp; location_name в пользовательской модели —
user = User.first
category = Location.find_by(name: location).category.downcase
price = Revenue.find_by(role_code: user.role_code).send(category)
puts "Your price is #{price}"
Ответ №5:
Простым способом получения цены было бы создать функцию, которая принимает объект Location (user_entered_location) и объект Revenue (user_entered_revenue) и возвращает цену.
def get_price(user_entered_location, user_entered_revenue)
if user_entered_location.category=="Urban"
return user_entered_revenue.urban
elsif user_entered_location.category=="Suburban"
return user_entered_revenue.suburban
else
return user_entered_revenue.rural
end
Вы также могли бы изучить объединение таблиц.