d2jsp
Log InRegister
d2jsp Forums > Off-Topic > Computers & IT > Programming & Development > 500fg For Solution With Activerecord / Sql Query > Ruby, Rails 4, Query Exact Match Habtm
Prev12
Add Reply New Topic New Poll
Member
Posts: 33,701
Joined: Jul 17 2006
Gold: 1,990.00
Jun 15 2014 04:53pm
Quote (carteblanche @ Jun 15 2014 03:46pm)
if colors.color_name is a single color, please show me sample data in your database to represent this.

assuming this is the colors table:
color_id = 1, color_name = black
color_id = 2, color_name = blue
color_id = 3, color_name = red
color_id = 4, color_name = green

i'm assuming this is how you set up your card:color correlations:

card_colors table:
card_id = 1, color_id = 4 -- this card is available in green
card_id=1, color_id = 2 -- this card is also available in blue

now how are you representing that the card is available in green, blue, and blue|green?

/edit: or is each card_id only associated with a single colour tuple?


Code
> Color.all
Color Load (2.4ms) SELECT "colors".* FROM "colors"
=> #<ActiveRecord::Relation [#<Color id: 1, color_name: "Blue", created_at: "2014-06-13 22:33:35", updated_at: "2014-06-13 22:33:35">,
#<Color id: 2, color_name: "Black", created_at: "2014-06-13 22:33:35", updated_at: "2014-06-13 22:33:35">,
#<Color id: 3, color_name: "Colorless", created_at: "2014-06-13 22:33:35", updated_at: "2014-06-13 22:33:35">,
#<Color id: 4, color_name: "Green", created_at: "2014-06-13 22:33:35", updated_at: "2014-06-13 22:33:35">,
#<Color id: 5, color_name: "Red", created_at: "2014-06-13 22:33:35", updated_at: "2014-06-13 22:33:35">,
#<Color id: 6, color_name: "White", created_at: "2014-06-13 22:33:35", updated_at: "2014-06-13 22:33:35">]>


for a green black card:
Code
> card = Card.find(6805)
Card Load (0.7ms) SELECT "cards".* FROM "cards" WHERE "cards"."id" = $1 LIMIT 1 [["id", 6805]]
=> #<Card id: 6805, name: "Deathrite Shaman", mana_cost: "{B/G}", loyalty: nil, img_link: nil, converted_mana_cost: 1.0, oracle: "{T}: Exile target land card from a graveyard. Add o...", rarity: "Rare", power: 1, toughness: 2, mtg_set_id: 31, created_at: "2014-06-13 22:35:39", updated_at: "2014-06-13 22:35:39">


Code
> card.colors
Color Load (2.4ms) SELECT "colors".* FROM "colors" INNER JOIN "cards_colors" ON "colors"."id" = "cards_colors"."color_id" WHERE "cards_colors"."card_id" = $1 [["card_id", 6805]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Color id: 2, color_name: "Black", created_at: "2014-06-13 22:33:35", updated_at: "2014-06-13 22:33:35">,
#<Color id: 4, color_name: "Green", created_at: "2014-06-13 22:33:35", updated_at: "2014-06-13 22:33:35">]>
Member
Posts: 32,925
Joined: Jul 23 2006
Gold: 3,804.50
Jun 15 2014 05:01pm
Quote (Kamikizzle @ Jun 15 2014 06:53pm)
Code
> Color.all
  Color Load (2.4ms)  SELECT "colors".* FROM "colors"
=> #<ActiveRecord::Relation [#<Color id: 1, color_name: "Blue", created_at: "2014-06-13 22:33:35", updated_at: "2014-06-13 22:33:35">,
#<Color id: 2, color_name: "Black", created_at: "2014-06-13 22:33:35", updated_at: "2014-06-13 22:33:35">,
#<Color id: 3, color_name: "Colorless", created_at: "2014-06-13 22:33:35", updated_at: "2014-06-13 22:33:35">,
#<Color id: 4, color_name: "Green", created_at: "2014-06-13 22:33:35", updated_at: "2014-06-13 22:33:35">,
#<Color id: 5, color_name: "Red", created_at: "2014-06-13 22:33:35", updated_at: "2014-06-13 22:33:35">,
#<Color id: 6, color_name: "White", created_at: "2014-06-13 22:33:35", updated_at: "2014-06-13 22:33:35">]>


for a green black card:
Code
> card = Card.find(6805)
  Card Load (0.7ms)  SELECT "cards".* FROM "cards" WHERE "cards"."id" = $1 LIMIT 1  [["id", 6805]]
=> #<Card id: 6805, name: "Deathrite Shaman", mana_cost: "{B/G}", loyalty: nil, img_link: nil, converted_mana_cost: 1.0, oracle: "{T}: Exile target land card from a graveyard. Add o...", rarity: "Rare", power: 1, toughness: 2, mtg_set_id: 31, created_at: "2014-06-13 22:35:39", updated_at: "2014-06-13 22:35:39">


Code
> card.colors
  Color Load (2.4ms)  SELECT "colors".* FROM "colors" INNER JOIN "cards_colors" ON "colors"."id" = "cards_colors"."color_id" WHERE "cards_colors"."card_id" = $1  [["card_id", 6805]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Color id: 2, color_name: "Black", created_at: "2014-06-13 22:33:35", updated_at: "2014-06-13 22:33:35">,
#<Color id: 4, color_name: "Green", created_at: "2014-06-13 22:33:35", updated_at: "2014-06-13 22:33:35">]>


ok, so each card_id has one colour tuple. eg a single card_id can't be available in both blue and green unless it's blue-green.

so here you go:

Quote
/edit: or is each card_id only associated with a single colour tuple? eg card_id and color_id together are unique? if that's the case, you're gonna hurt yourself with performance, essentially using a view to put it into the same design i had it in originally.

ex:
select cards.card_id, blue.color_id, green.color_id from cards
left join card_colors blue on cards.card_id = blue.color_id
left join colors cblue on blue.color_id = cblue.color_id
left join card_colors green on cards.card_id=green.color_id
left join colors cgreen on green.color_id = cgreen.color_id
.... keep joining all the card colours
where cblue.color_name = 'blue' and cgreen.color_name = 'green'


you're essentially trying to normalize your colours. i'd go with my original recommendation and say drop card_colors and colors tables and just stick your color columns on your cards table. but if you insist on keeping it this way, just use a view that i mentioned above to denormalize it. maybe wrap it with a nvl/coalesce/if/case or whatever it's called to convert it to N/Y format

This post was edited by carteblanche on Jun 15 2014 05:06pm
Member
Posts: 33,701
Joined: Jul 17 2006
Gold: 1,990.00
Jun 15 2014 05:25pm
Quote (carteblanche @ Jun 15 2014 04:01pm)
ok, so each card_id has one colour tuple. eg a single card_id can't be available in both blue and green unless it's blue-green.

so here you go:



you're essentially trying to normalize your colours. i'd go with my original recommendation and say drop card_colors and colors tables and just stick your color columns on your cards table. but if you insist on keeping it this way, just use a view that i mentioned above to denormalize it.


Code
ex:
select cards.card_id, blue.color_name, green.color_name from cards
left join card_colors blue on cards.card_id = blue.color_id
left join colors cblue on blue.color_id = cblue.color_id
left join card_colors green on cards.card_id=green.color_id
left join colors cgreen on green.color_id = cgreen.color_id
.... keep joining all the card colours
where cblue.color_name = 'blue' and cgreen.color_name = 'green'


so because, the colors will come in from a form, how do i dynamically input those colors? because i obv cant just hard code blue.color_name.
all in all its starting to look like this is not a good format for the db. ill probably try to bitmap it like your suggestion.

This post was edited by Kamikizzle on Jun 15 2014 05:34pm
Member
Posts: 32,925
Joined: Jul 23 2006
Gold: 3,804.50
Jun 15 2014 05:38pm
Quote (Kamikizzle @ Jun 15 2014 07:25pm)
Code
ex:
select cards.card_id, blue.color_id, green.color_id from cards
left join card_colors blue on cards.card_id = blue.color_id
left join colors cblue on blue.color_id = cblue.color_id
left join card_colors green on cards.card_id=green.color_id
left join colors cgreen on green.color_id = cgreen.color_id
.... keep joining all the card colours
where cblue.color_name = 'blue' and cgreen.color_name = 'green'


so because, the colors will come in from a form, how do i dynamically input those colors? because i obv cant just hard code blue.color_name


you talking about the where clause in the SELECT or in the INSERT?

at this point, i assume your view looks like this:

vw_cards:
columns:
t.integer "card_id"
t.string "name", null: false
t.string "mana_cost"
t.integer "loyalty"
t.string "img_link"
t.float "converted_mana_cost"
t.text "oracle"
t.string "rarity"
t.integer "power"
t.integer "toughness"
t.integer "mtg_set_id"
t.datetime "created_at"
t.datetime "updated_at"
// boolean, integer, string, whatever
"has_blue"
"has_green"
"has_black"
"has_red"
"has_white"

and i'm guessing you have some sort of checkboxes on your screen, and the user checks each one?

so you'd say select * from vw_cards where has_blue=? and has_green=? and has_black=? and has_red=? and has_white=?

and you pass in chkHasBlue.isChecked(), chkGreen.isChecked(), chkBlack.isChecked(), chkRed.isChecked, chkWhite.isChecked()
Member
Posts: 29,723
Joined: Jun 11 2007
Gold: 279.52
Jun 16 2014 05:55am
lol use php....ruby syntax looks weird to me..wish i could be more help
Member
Posts: 29,723
Joined: Jun 11 2007
Gold: 279.52
Jun 16 2014 06:44am
Actually(stupid jsp said i didint have permission to edit):

lol use php....ruby syntax looks weird to me..but im familar with mysql and mtg

honestly i think you should store the card with the colors or color_ids

for instance in your vw_cards table do:
t.string "card_colors"

and insert it as "black" or "black,green" or "black,green,blue" ect

also i would add a 6th color: colorless, just for cmc reasons.

anyways, if you dont, i think it would make it easier

just do something like:
Code
"select * from vw_cards where card_color LIKE '%black%' AND LIKE '%black,green'%"


or this might even be better:
Code
"select * from vw_cards where card_color LIKE '%black%' AND LIKE '%black,green'% AND NOT LIKE '%green%'"


anyways i think that would work, you can always figure out how to set that up with your checkboxes

such as:

black: checked
green: checked

some cool javascript code that handles options based on colors chosen:
search for:

black:checked
black green:checked
green:unchecked

or exlude:
Multicolor:unchecked
mono black: unchecked
green: checked


then if it was me...i would do an ajax call on search... but up to you.

This post was edited by AkuuZ on Jun 16 2014 06:44am
Member
Posts: 33,701
Joined: Jul 17 2006
Gold: 1,990.00
Jun 16 2014 08:34am
Quote (AkuuZ @ Jun 16 2014 05:44am)
Actually(stupid jsp said i didint have permission to edit):

lol use php....ruby syntax looks weird to me..but im familar with mysql and mtg

honestly i think you should store the card with the colors or color_ids

for instance in your vw_cards table do:
t.string "card_colors"

and insert it as "black" or "black,green" or "black,green,blue" ect

also i would add a 6th color: colorless, just for cmc reasons.

anyways, if you dont, i think it would make it easier

just do something like:
Code
"select * from vw_cards where card_color  LIKE '%black%' AND LIKE '%black,green'%"


or this might even be better:
Code
"select * from vw_cards where card_color  LIKE '%black%' AND LIKE '%black,green'% AND NOT LIKE '%green%'"


anyways i think that would work, you can always figure out how to set that up with your checkboxes

such as:

black: checked
green: checked

some cool javascript code that handles options based on colors chosen:
search for:

black:checked
black green:checked
green:unchecked

or exlude:
Multicolor:unchecked
mono black: unchecked
green: checked


then if it was me...i would do an ajax call on search... but up to you.


yea im going to get started on carteblanche's suggestion today. ill probably build a 5-bit binary map for the form submission and some methods to convert that into the 5 color true false queries (which will work for colorless being 00000). passing around a string/binary value will make it alot easier. and in general search functions are an easy get request. the reason i dont want to ajax it is because pressing back break the user flow. and typically when i search im going back and forth all the time (instead of pressing the search button again).

i dont want to just hard code a string value in there like that because it leaves room for 0 flexibility and its a pretty unconventional way of doing things. because this is just a pet project (for learning sake), adopting best practices is a priority. in retrospec, looking into a nosql db would probably have been the best solution, but i defaulted to postgresql because ive never used a nosql

This post was edited by Kamikizzle on Jun 16 2014 08:37am
Member
Posts: 33,701
Joined: Jul 17 2006
Gold: 1,990.00
Jun 16 2014 10:34am
well holy fuck. you can use arrays as a column type in rails 4
this solves all my problems http://reefpoints.dockyard.com/ruby/2012/09/18/rails-4-sneak-peek-postgresql-array-support.html
Member
Posts: 29,723
Joined: Jun 11 2007
Gold: 279.52
Jun 16 2014 07:32pm
Quote (Kamikizzle @ Jun 16 2014 02:34pm)
yea im going to get started on carteblanche's suggestion today. ill probably build a 5-bit binary map for the form submission and some methods to convert that into the 5 color true false queries (which will work for colorless being 00000). passing around a string/binary value will make it alot easier. and in general search functions are an easy get request. the reason i dont want to ajax it is because pressing back break the user flow. and typically when i search im going back and forth all the time (instead of pressing the search button again).

i dont want to just hard code a string value in there like that because it leaves room for 0 flexibility and its a pretty unconventional way of doing things. because this is just a pet project (for learning sake), adopting best practices is a priority. in retrospec, looking into a nosql db would probably have been the best solution, but i defaulted to postgresql because ive never used a nosql


i didnt mean a literal string, sorry.
in your jquery get() u would pass the is_colors and not_colors in a function, and post them to you back end request page and do the querys using the variables..you might have M-D arrays you can break them down if you need..

$color_search1 = colors[0][1] or w/e..just count length and you should be fine... thats prolly what i would do...but idk
Go Back To Programming & Development Topic List
Prev12
Add Reply New Topic New Poll