12.28.05

rubyGreg: Learning Rails

Posted in html/css, computers, Gregarius, ruby/rails at 10:36 pm by Haris

The time has finally come for me to jump on the Rails-wagon and learn Ruby on Rails. I will document here my efforts to port the fabulous Gregarius feed aggregator to Ruby. I admit this is not a tutorial for the complete novices, and definitely of no use to a seasoned Rails developer, unless they enjoy a good laugh. In particular, I am assuming that you have glanced at the standard tutorials here and here, as well as Amy Hoy’s wonderful list of articles on her site. I am sure there are other worthwhile tutorials out there, and you can probably find them documented at the wiki.

So to recap, I am assuming that you have Ruby and Rails installed and you have two terminal windows open, as well as your favorite editor ready to work on any file in the directory we are about to create, and of course your favorite browser open, so that we can view our results. Also keep in mind that whatever is presented here is my view on things, and it might very well be incomplete/inaccurate. Please feel free to correct me. This might also be an opportune moment to have a look at the Gregarius source code, to have some idea what we are trying to replicate. Of course for now we’ll only do some small bits of the overall monster.

Ready? Alright then, on with the show!

First, let’s create the basic structure for our website, the first thing that Rails does for us for free. So in one of our terminal windows we’ll move to the location we want our new website created. In my case, that would be ~/Desktop/RoR/Rails, but of course your milage may vary. Now, to create the website. This just means running the command rails rubyGreg. As you might have guessed, rubyGreg is the name for our port. If you have followed the aforementioned tutorials, you know that what has just happened is that a huge collection of files has just been created for you for free, all living in a subdirectory called rubyGreg. Let’s cd to that directory, and see what subdirectories are there.

  1. app. That sounds important. We’ll be spending a lot of time here.
  2. components. Hm, I have no idea what this is for, so I’ll ignore it for the time being.
  3. config. We’ll probably need to customize something here, at the very least tell Rails what database we are using.
  4. db. Hm, no idea here either, sounds like it should have to do something with the database. We’ll see if we need that.
  5. doc. Ok, that’s obviously here so that we can document our exploits. Seems to have a README inside of it.
  6. lib. Sounds reasonable. We’ll see…
  7. log. Good, logging is always good to have. Let’s see what Rails logs by itself.
  8. public. I learned from Amy what that is for: javascript, css, images, standard error pages etc.
  9. script. That you hopefully already know about. This contains some scripts to automate lots of things. We’ll use it a lot in a moment.
  10. test. This is to prepare automated tests for our app. I’ve never written tests before, time to start. It already seems to have some stuff in there.
  11. vendor. I think I’ll ignore that for now.

Ok, that’s a lot of stuff, but we’ll ignore most of it. The place to start is a database to play with. I’ll use a test gregarius database that I have around just for this reason. You can get it here. I assume here that you know how to set up a database and give the right permissions to a user. Keep in mind that if you are using mysql, you will need to have an account with a password of the new type, and not the old type. Once you have the database going, you need to edit the file config/database.yml accordingly. Good, we are done!

Ok I lied, we’re not done yet, now the fun part begins. Time to talk about the app directory, and the MVC design pattern. I will actually assume you don’t know what MVC is, and will attempt to explain. MVC is a standard design pattern for the general structure of an application. The initials stand for Model-View-Controller.

  1. The Model is a class that is responsible for the data of our application. This is in charge of getting the data from the database and saving/deleting/creating it. So it is the first level of abstraction on top of the database, so that our program doesn’t have to talk to the database directly.
  2. The View is a class that is responsible for the presentation of the data to the user. Think of it as the usual mixed HTML/PHP files you often deal with to send the data back to the client.
  3. The Controller is the class that coordinates the other two classes. This is the heart of the application.

In a typical run of the program, the controller will first figure out what the client has asked for. Then, it will ask the model for the appropriate data. Then it will process this data, if it needs processing, and then it will send the data to the view for display. This is a very important point. When we build our app we need to keep this in mind. We’ll see an example of how this works in a minute. Now, on to create our controllers, models, and views.

Before we do that, we need to do one more thing, and that is to check that things have been set up correctly. Luckily for us, one of the things that the rails command we executed above created for us was a mini server to use for testing things. And this is where our second terminal window will be used (I’m sure you were dying to find out what that was for, eh?). So go ahead and switch to that window, and move to the directory rubyGreg that we just created. Now run script/server. You should see some nice messages about WEBrick running, along with a web-address, http://0.0.0.0:3000 in my case. If you point your browser to this address, you will actually see our app running! Yes, I know it doesn’t feel much like our app yet, what did you expect without writing a single line of code? But it is running!

Alright, now finally we’ll create our controllers, views etc. Let’s move to the other terminal window, which is also at the rubyGreg directory. Our aggregator basically deals with two things, items and channels. So we’ll create two controllers and models to go with that. Run script/generate controller Item. You will notice this created the following files:

  1. app/views/item. The views subdirectory is the one where all the views will reside. It will be filled with .rhtlm files. It will also contain one subdirectory for each controller. Here the item subdirectory is associated to the Item controller we created above.
  2. app/controllers/item_controller.rb. The controllers subdirectory will of course contain the controllers. These will be ruby code files, that we will be working a lot with.
  3. test/functional/item_controller_test.rb. This is a file to add the tests for the controller. I’ll worry about those a bit later.
  4. app/helpers/item_helper.rb. As I learned from Amy, the helpers are little methods to do stuff for you, and this file is to add our own helpers. Something to worry about later too.

Ok, so not too much happened for now. We just got a controller and a view for our items. Now we need a model. Go to the terminal window again, and run script/generate model Item. This created the following files:

  1. app/models/item.rb. This is the file that does the modeling work for us. It is magic in many ways, as we’ll see.
  2. test/unit/item_test.rb. For the unit tests for the model, obviously.
  3. test/fixtures/items.yml. Hm, this is again part of the testing package. I’ll investigate all that at a later post.

Ok, now we need to do the same for the channels, so let’s run the commands script/generate controller Channel and script/generate model Channel. And now, we are ready to do some magic. Let’s start by a simple task: Create a page that contains a list of all the channels, probably appropriately called index. To do that, the first thing to do is add an index method to the channels controller. This will be the file app/controllers/channel_controller.rb, but from now on I will not mention full paths like that. In this method, all the controller has to do is ask the channel model for all channels, and store those in some controller variable so that the view can get hold of them. Remember, the key idea is that the view and the model are only allowed to communicate with the controller, and not each other. So the code to be added between the class ... line and the final end line would be just:

def index
  @channels = Channel.find_all
end

So let’s explain this for a second. The def index line defines a new function with name index. The code for the function is everything enclosed between that line and the corresponding end. The line in the middle tells the model Channel to execute the method find_all, which just returns an array of all channels. Then this is stored in the instance/controller variable @channels. All instance variables need to start with the symbol @.

Now we need to arrange for the view of this table of data. This will be done by creating a file titled index.rhtml, and placing it in the views/channel directory. We’ll need to change this file later, namely in two paragraphs, but for now let’s just add the following there:

<html>
    <body>
        <h1>All Channels</h1>
        <ul>
            <% @channels.each do |channel| %>
                <li><%= channel.title %></li>
            <% end %>
        </ul>
    </body>
</html>

To see what this would produce, point your browser at http://0.0.0.0:3000/channel/, or perhaps different numbers depending on what WEBrick told you it would understand. If all has gone well, you should see something like this:

First image: a simple list

Let’s take a closer look at the above code though. You will notice the typical idea of mixing html markup with code, except with a tiny twist: There are two ways to insert code: <% Code here %> or <%= Code here %>. As I understand it, the former just executes that code, without inserting anything in, while the latter inserts at that point in the html the value returned by the last operation in the code. (Ok, maybe there is a similar trick in PHP, if so, I admit ignorance). The important lines above are of course the three lines between <ul> and </ul>. The first one looks at the @channels array, and for each element of the array executes the block starting with do and ending with end. Each time through the block, the element is captured by the local channel variable, which is what the |channel| in the first row indicates. For each of those channels, we ask the channel to return us its title and this is then placed in the html output enclosed in li tags.

Well, that’s probably not very exciting, is it? We would probably like to have it so that each channel title is actually a link, and clicking on the link loads up a list of articles. For this we will use the Rails command link_to, which creates such a link. You can read more about it in the built in documentation, which in my installation is at file:///usr/lib/ruby/gems/1.8/doc/actionpack-1.11.1/rdoc/index.html. The thing to decide is whether the responsibility for showing a list of items from a particular channel should be the responsibility of the channels controller or the items controller. For now I will put it in the channels controller. All one has to do is change the line:

<li><%= channel.title %></li>

to:

<li><%= link_to channel.title, {:action => "list_items", :id => "#{channel.id}"} %></li>

So what happened here? link_to is a method that will create a link. The rest of the stuff in this line is arguments to that method. One could also have written it more traditionally as:

<li><%= link_to(channel.title, {:action => "list_items", :id => "#{channel.id}"}) %></li>

Fortunately, Ruby is very lax about this short of thing, it has a very minimalist syntax. That’s also the reason we don’t need to put semicolons anywhere, though we could if we wanted to. The first argument is of course the text of the link. The thing in the braces is a hash table, which associates to :action and :id the values "list_items" and "#{channel.id}" respectively.

What is :action you ask? The colon in front indicates that this is to stand for the symbol for the method action. This tells Rails what method to call from our controller, in this case the method called action. :id is just some extra information that the controller will be able to use in order to find out what channel’s items to display. The "#{channel.id}" part tells Ruby to execute the ruby code channel.id, and then store the result in the string. Just to give you another example, "#{3+4}" will result in "7", while "#{a=2;a+2}" will return "4".

How does this turn into a URL for the link? I have no clue, but that’s what link_to takes care of for us. Now try it out. Reload the page on your browser and try to click one of the channels. You will probably see:

Second image: unknown action

Why did this happen? Well, simple enough, as the error message says: We have not implemented a list_items action yet. Before we do that, we need to change our database a little bit, namely the names of the tables. Rails uses a set of conventions for table and column names that helps it find things without us explicitly telling it about them. Now, if you look at the SQL schema for our database, you’ll notice that the table for the items is called item. Rails uses the convention that the model name should be singular and capitalized, while the corresponding table name should be plural and not capitalized, i.e. Item -> items, Channel -> channels and so on. There are two ways to fix that. The one is to change the table name. The other is to go to the file app/models/item.rb and add the line set_table_name "item". I will opt for the first option.

The second change that needs to take place is the column named cid in the items table. This is a foreign key corresponding to the channel id, and so the convention that Rails imposes on this is that it should be named channel_id. Once again there are two ways to fix it, the simpler one being renaming it to channel_id. I will mention the second one right now, along with the changes in the model that need to be made. Basically, we need to tell our items that they belong to channels, and our channels that they have items. So in the Item model file, add the line:

belongs_to :channel

or if you did not change the column name for cid, add instead the line:

belongs_to :channel, :foreign_key => "cid"

Also, in the Channel model file, add the line:

has_many :items

Now we’ve told our models all they need to know about each other. Let’s implement list_items now. In the channels controller, add the following method:

def list_items
  @channel = Channel.find(@params['id'])
  @items = Item.find_all_by_channel_id(@params['id'])
end

Also in the app/views/channel directory, create a new file called list_items.rhtml, with code:

<html>
    <body>
        <h1><%= @channel.title %></h1>
        <ul>
            <% @items.each do |item| %>
                <li><%= link_to(item.title, {:action => "details", :id => "#{item.id}", :controller => "item"}) %></li>
            <% end %>
        </ul>
        <%= link_to("See all items from this feed.", {:action => "list_details",  :controller => "item", :channel_id => "#{@channel.id}"}) %>
    </body>
</html>

This is not exactly how these appear in Gregarius but for now I’m just trying to see how some things work. We’ve seen most of this code before. The only thing that’s new is the , :controller => "item" bit. That’s there because currently we are in the channels controller, but we would like this action to be executed from the items controller. We just created two new actions for the items controller, so we should implement them, as well as the corresponding views. So add the following code in the items controller:

def details
  @item = Item.find(@params['id'])
end

def list_details
  @channel = Channel.find(@params['channel_id'])
  @items = Item.find_all_by_channel_id(@params['channel_id'])
end

Also create files app/views/item/details.rhtml with code:

<html>
    <body>
        <h1>Item details</h1>
            <div><h2><%= @item.title %></h2>
                <p>Posted by: <%= @item.author %> on <%= if @item.pubdate.nil? then @item.added else @item.pubdate end %></p>
                <p><%= @item.description %></p>
            </div>
    </body>
</html>

and app/views/item/details.rhtml with code:

<html>
    <body>
        <h1><%= @channel.title %></h1>           
        <% for item in @items do %>
            <div><h2><%= item.title %></h2>
                <p>Posted by: <%= item.author %> on <%= if item.pubdate.nil? then item.added else item.pubdate end %></p>
                <p><%= item.description %></p>
            </div>
            <% end %>
    </body>
</html>

Ok, this will be enough for now. Next time I’ll deal with using layouts to get rid of a lot of the common glue code in all of the forms above, and try to get the options menu in, and finally make it start looking more like gregarius.

Later

5 Comments »

  1. Marco said,

    December 29, 2005 at 2:00 am

    Tu quoque, Brute, fili mi! ;-)

    Seriously though, it’s quite interesting to see how the same application logic is implemented in a totally different paradigm. I wish you best of luck if you intend to go the whole way!

  2. Sameer said,

    December 29, 2005 at 2:25 pm

    oh nice!! can we see a demo? I think dreamhost has ruby on rails.

    Oh btw, the links in this post need to be fixed….

  3. Haris said,

    December 29, 2005 at 10:20 pm

    Thanks Sameer, links should be fixed now.
    As per Sameer’s request, here it is running:

    http://rubygreg.skiadas.dcostanet.net/channel/index

    Doesn’t look pretty yet, and can do very little at the moment, but what did you expect with 34 lines of code?

  4. Rich said,

    January 6, 2006 at 6:52 am

    Haris, the wiki link in the first paragraph does not resolve. The following is displayed:
    Not Found
    The requested URL /afterthought/2005/12/28/rubygreg-learning-rails/wiki.rubyonrails.com/rails was not found on this server.

    Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.

  5. Haris said,

    January 6, 2006 at 7:42 am

    Thanks Rich, good catch. It seems Markdown and I don’t communicate very well when it comes to links. It should be fixed now.

Leave a Comment

macrobid more drug side effects buy neurontin fosamax lawsuits effects of fluoxetine order tamiflu buy meridia online effexor overdose minocycline hcl paxil overdose potatoes not prozac temazepam tablets adipex no rx side effects of lamisil drug elavil heroin chic metformin oral flomax erection butalbital apap impotence monopril flextra medicationflomax diazepam without a prescription generic aciphex meclizine drug what is flonase levaquin oral aldara side effects phentermine diet pill medroxyprogesterone acetate online pharmacy vaniqa fluconazole online macrobid oral fosamax generic propecia prices paxil side affects methamphetamine arrests fluconazole pregnancy naprosyn oral nexium more drug side effects cephalexin oxazepam drug information ramipril lawyer pantoprazole formulation aciphex rebate buy levitra antivert side effects ortho cyclen viagra no prescription generic for norvasc premarin alternatives buy remeron antibiotic penicillin altace side effects xanax for sale protonix side effects vicoprofen online allegra and aciphex interaction phentermine 375 mg drug aciphex fluconazole and dangerous nexium oral mescaline cactus shooting flexeril buy phendimetrazine online buying vicodin drug tamoxifen doxazosin buy vicodin what is seroquel buy proscar keppra to treat depression famvir dosage buy synthroid without prescription marion jones steroids serevent steroid prozac side effect ortho molecular products atenolol reviews no prescription needed adipex lavorazione hashish in marocco what is sertraline discount tenuate what is tricor vicoprofen without perscriptionvioxx generic propecia sertraline oral what is cephalexin keflex no prescription where to buy steroids buy oxycontin without a prescription tramadol hcl acetaminophen viagra price ditropan alternatives ambien withdrawl soma buy levitra price buy acyclovir drug crystal methamphetamine premarin generic oxycontin abuse buy lexapro online prescription soma triphasil tabs online meds fioricet fioricet oral generic plavix vioxx lawyer nexium alternative buy tamiflu online fulvicin price paroxetine suicidal pepcid buy buy levitra online tamiflu from canadatamoxifen seroquel oral levoxyl and weightloss celebrex 200mg cialis without prescription risedronate 35mg glyburide side effects actos diabetes sildenafil cheap generic valacyclovir online fioricet effects prozac weight gain lorcet without rx mircette birth control pills buy ambien without a prescription tenuate dospan watson generic zocor anabolic steroids buy what is metoprolol prilosec informationprinivil clonazepam overdose meridia order buy cyclessa buy fosamax methamphetamine recipe imitrex oral buy anabolic steroids protopic children mircette without a prescription from us pharmacy history of phencyclidine what is microzide used forminocycline xanax without a prescription online pharmacy fioricet buy xanax on line alternative to fulvicin cheap renova without a prescription temazepam 15 mg tobradex sales oxycodone addiction flexeril drug carisoprodol online pharmacy what is the price for prinivil xanax oral tamiflu medication antabuse online triphasil rohypnol drug alternative to metrogel buy ultracet without prescription what is macrobid used for vicodin cod altace ramipril antabuse side effects cialis comparison levitra elavil medicine vicodin high famvir pregnancy new dilantin didrex atlanta steroids and sports nardil online pharmacy best price viagra tadalafil coupon norvasc side effects ativan data synthroid more drug side effects buy didrex tadalafil online acetaminophen discovery of penicillin soma watson tylenol codeine plendil blood pressure medicine prednisone withdrawal synthroid oral macrobid doses sertraline hcl naprosyn side effects promethazine buy tazorac potency pravachol bontril aceon oxycodone side effects tamiflu buy drug valium phentermine cheap tamoxifen breast cancer compazine and side effects glyburide interaction zithromax pregnancy evista concerns cheap flonase hyzaar generic cyclobenzaprine effects nasacort aq nasal spray levothroid weight loss tadalafil overnightt finasteride cheap nifedipine xr buy rabeprazole buying sibutramine making mdma tadalafil price captopril side effects online pharmacy sibutramine buspar medicine valtrex side effects zovirax cost high testosterone meridia price lexapro dosage steroids side effects buy vicodin without a prescription online pharmacy no prescription proscar phentermine prescription online esgic genericesomeprazole meridia weight loss actos side effects oxycodone pills testosterone booster valtrex price generic prilosec lortab abuse buy adipex online order hydrocodone what is elocon dog pepcid ac or zantac ranitidine drug viagra cialis levitra propecia pharmacy phencyclidine picture generic sarafemselsun blue famvir vs valtrex snorting zoloft vaniqa medicine buy tenuate without a prescription generic vicoprofen phentermine prescription treating vicodin withdrawl cipro side effects in women ultracet online alternative celebrex generic xenical methylprednisolone tablets genarit norvasc prilosec 20mg vicodin pictures starting klonopin prilosec online ambien overnight delivery generic vicodin biaxin problem tadalafil 20mg steroids online is ultram a narcotic buy viagra alternative miacalcin more drug uses flomax caps side effectsflonase definition prozac vicodin buy online buy nasacort oxycontin addiction hyzaar medication buy ramipril on line without prescriptionranitidine biaxin nexium histex 10mg dilantin buy lorazepam keppra weight gain diclofenac buy xenical otc albuterol advair inhaler online pharmacy flonase fioricet tablets tricor generic mononitrate tylenol during pregnancy omeprazole oral buy detrol child taking lisinopril tylenol pregnancy ativan complication lortab cod cheap k-dur tamiflu relenza famvir oral paroxetine withdrawlpatanol nizoral hair loss buy fulvicin flovent inhaler nicotrol inhalers lortab side effects antabuse drug zyprexa withdrawal nordette levora tadalafil generic provigil more drug uses cheap generic viagra barry bonds steroids viagra samples buy hydrocodone online flexeril generic fluconazole overnight delivery buy diazepam without prescription buy evista propecia prescriptions antibiotic macrobid online pharmacy sildenafil generic lipitor ionamin pills prempro without a prescription buy valporicvaltrex order xanax online vaniqa buy what is rabeprazole sodium paxil stopping is naisads in motrin cefixime xenical no prescription toprol medication buy lorazepam online serevent discus viagra online uk premarin withdrawal aldara zocor generic tamiflu require prescription oxycontin side effects natural testosterone temovate buy ultravate drug omeprazole overdose lortab no prescription needed oxycodone pictures ibuprofen buyimitrex omeprazole generic ecstasy pills proscar propecia smoke flexeril premarin creme clomid buy veterinary fulvicin metrogel topical gel fioricet generic qualitest drug spironolactone amoxycillin evista side affectsevoxac adipex online prescription approved online tramadol pharmacy what is k dur tabletsk-dur order hydrocodone online bupropion cheap paxil hydrocodone picture dosage of pravachol trazodone and pregnancytretinoin prednisone dosage adderall metformin and weight loss proscar forum orlistat xenical serevent lawsuit order ultram order phentermine online sarafem 10mg temazepam cap prescription adderall xr increase effects of oxazepam vaniqa lowest price rabeprazole buy generic sildenafil cheapest sibutramine levitra and cialis and viagra free generic levitra morphine generation cheap valium gemfibrozil buyghb zoloft side effects nardil on line generic serevent tamsulosin hydrochloride evoxac more drug uses plavix medicine mdma for salemeclizine xenical without prescription serzone withdrawal side effects of clomid what is ic butalbital paroxetine 20 mg synthroid without a prescription amaryl diabetic medication hydrocodone cod what is toprol trimox picture valtrex cheap aricept side effects soma prescriptions diovan buy vicodin generic allegra prescription uses for temovate medicinetenuate lorazepam withdrawal clomid side effects famvir coupons rohypnol pictures zestril oral is ativan addictive seroquel abuse cheap zithromax online valium no prescription pictures of mescaline penicillin allergy online tramadol phentermine side effects dangers famvir medication pictures what is terazosin viagra generic lortab online isosorbide buy isosorbide mononitrate oral zithromax antibiotic norvasc overdose how does didrex work tamoxifen citrate free nicotrol inhalernifedipine pharmacy usa lipitorlisinopril nardil parnate premarin side effects testosterone gel nexium price k-dur transdermal patchkeflex alcohol and prozac avodart flomax lortab addiction tretinoin for genital warts how to make heroin adderall prices dovonex what is folic acid propecia reviews order norco online buy spironolactone no prescriptionsteroids buy preven buy xanax using paypal augmentin online pharmacy prempro trial cheapest phentermine prices what is pcp clonidine side effects cheap generic levitra onlinelevothroid clarinex compared to claritin rosiglitazone actions what is folic acid for buy soma online protonix more for patients prilosec coupons buy serzonesibutramine side effects when taking gemfibrozil effexor drug side effects stopping prozac vicodin sleepiness buy atorvastatin buy generic triphasil what is atenolol zithromax online aciphex costs buy ketamine online propecia testimonials buy injectable anabolic steroids xanax 2mg order tamiflu without prescription hydrocodone buy relafen drug kenalog shots wellbutrin withdrawal symptoms history of steroids buying valium online pravachol drug interactions buy fioricet w codeine side effects flomax sumatriptan from mexico cardura fabric esomeprazole magnesium uses of penicillin renova buy clonazepam fedex renova without prescription promethazine pill lotrel low pulse rate tadalafil cialis from india lortab without prescription side effects of diazepam buy adderall pills cyanocobalamin buy ultram withdrawal tamsulosin hcl propoxyphene apap serevent inhaler what does oxycodone look like sarafem canada flexeril online soma medication didrex side effects zyban buy provigil 200mg tab generic dovonex what is nexium buy valtrex alprazolam xr what is finasteride generic nasonex metformin dosage lasix without a prescriptionlescol diflucan adderall withdrawal generic premarin no prescription generic valtrex buy cheap generic nordette transderm pioglitazone hydrochloride accupril buy reactions to amoxycillin medication nexium protopic and vitiligo monopril side effects skelaxin side effect hydrocodone lortab generic zoloft proscar and pregnancy purchase xanax online order xenical seroquel buy fluconazole side effects about sertraline discount phentermine overnight fedex wellbutrin withdrawal proscar without prescription roxicet pill fosamax buyfulvicin valtrex girl oxazepam abuse carisoprodol online soma generic sibutramine adipex without prescription methylphenidate side effects ultram drug manufacturer of prinivil buy triamterene online glucophage and weight loss zovirax more drug uses vicodin withdrawlsvicoprofen relafen medication metrogel vaginal celebrex celecoxib phendimetrazine side effects adderall buy alprazolam online fedex mircette more drug side effects nasacort nasal spray order famvir ortho tri-cyclen side effects of keppra buy sibutramine meridia litigations minocycline without prescription generic xanax avandia drug alesse side effects cheap vermox online trazodone hcl tadalafil cod valium on line buy ketamine trazodone and clonazepam buy prinivilproctocort buspirone abuse accolate buy detrol and relief discovery penicillin tylenol with codeine canadaultracet xanax generic propoxyphene abuse lortab information buy zanaflex online buy depakote without a prescription antivert drug purchase phentermine online generic avapro lipitor muscle problems neurontin gabapentin miralax for children purchase fioricet online buy ultracet online no prescription patanol canada keflex oral celexa online pharmacy xanax no prescription clomid and pregnancy oxycontin for sale alternative viagra trazodone dosage buy tenuate dospan bontril no script kenalog lotion buy benicar avapro interactions buy macrobid without prescription metrogel side effects valium dosage what is flextra seroquel and alcohol what is levaquin generic for evista medicines what is famvir cardura buy generic ultram overdose roxicet erection viagra ibuprofen side effects what is nifedipine celecoxib alternative phencyclidine drugs low dose naltrexone prilosec nexium toprol information nifedipine cream order zithromax online what is supraxsymmetrel lorcet no prescription cyclobenzaprine 10mg side effects of lotrel prozac more drug uses side effects of ultram cipro no prescription purchase meridiamescaline yasmin buy no prescription ionamin lanoxin side effects sildenafil 100mg nasonex no rx what is trazodone valium online generic for altace overnight xanax online pharmacy tramadol propranolol hydrochloride cheap ultram online cheapest viagra online prescription tamiflu lotrisone more drug uses lipitor side effect lotensin dosage facts on ecstasy xanax xr estradiol levels cheap nasonex cyanocobalamin levoxyl and weight loss online prescription for adipex buy levaquin what is sibutramine zyban information buy tramadol side effects of propranolol purchase vicodin online phendimetrazine pills evista more drug interactions fioricet and pregnancy valtrex during pregnancy fioricet medication meridia side effects withdrawal symptoms of prednisone buy ambien buy naprosyn xanax valium buy proctocort alcon patanol nizoral pills toprol medicine valtrex and pregnancy nexium side effect cozaar cough vicodin addiction flomax tamsulosin canada order soma online mescaline dosage and effectsmetformin online pharmacy ceftin drug metoprololmetrogel what is plavix clopidogrel buy what is ritalin xanax abuse buy generic allegra fexofenadine cheap zithromaxzocor morphine sulphate didrex no prescription needed adipex review who discovered ionamin neurontin lawsuit ceftin side effects heroin overdose side effects of naprosyn adipex without rx zocor side affects ultram prescription gemfibrozil more drug uses adipex alternatives what is soma order phendimetrazine buy viagra on line promethazine codeine buspirone hydrochloride soma bicycles horse steroids pantoprazole label carton zanaflex dosage didrex drug discount zocorzoloft roxicet oral cialis levitra sale viagra side effects of ramipril ultram pain medication metformin more drug side effects side effects of miacalcin generic levoxyl purchase soma online elocon ointment adipex side effects brain purchase sildenafil citrate buy amoxil vioxx news norvasc side effect pravastatin side effects actonel buy ranitidine buyrelafen buy furosemide without a prescription miacalcin cause pancreatitis medication butalbital how to make mdma buy phentermine without prescription prevacid pregnancy prednisone tablets verapamil side effects serzone claims fluoxetine and pregnancy where to buy tramadol osteonecrosis and fosamax enalapril side effects buy zovirax without prescription how to use steroids lorazepam dosage prozac nation what is microzide fluconazole and natural medicine lamisil forums buy retin a online viagra for women what is azmacort tetracycline online lexapro more drug interactionslipitor buy generic sertraline buy wellbutrin premarin no prescription loratadine overdoselorazepam cheapest propecia discount xanax what is thiamine mononitratemonopril pantoprazole side effects what is zovirax bontril online pharmacy lexapro and weight gain medrol dosepack advair diprolene generic ramipril oral serzone increased energy premarin vaginal cream what is tobradextoprol tadalafil tablets skelaxin drug renova without a perscription what is risperdal patanol opht cozaar side effects buspirone hcl dangers of steroids nasonex nasal spray description triphasil acyclovir valacycovir on line phentermine tadalafil comprar retin a melanexmeridia what is estradiol plendil incontinence soma pharmacy buy sildenafil citrate cyclobenzaprine flexeril what is protonix steroids pictures cheap nexium tylenol biaxin reaction ritalin adhd nexium without prescriptionnicotine nordette and no prescription and thailand evista generic valium vicodin oral nexium pill phentermine pill imitrex coupons cheap celebrex online chemical name for suprax buy tussionex without prescription norco bike norco wolverine what is glyburide ritalin alternatives fluoxetine 20mg flonase nasal spray child paxil buy meridia on line buy zestrilziac risperdal overdoseritalin lotrisone lotion skelaxin medication purchase finasteride canadafioricet skelaxin dosage thiamine mononitrate formula tramadol on line side effects of flomax acyclovir aura soma furosemide prescription oxycodone overdose prozac information ketamine effects what is methylphenidatemethylprednisolone aciphex rabeprazole paxil lawsuit what is restoril buy prozac flexeril more drug side effects order tramadol online metrogel vaginal cream snorting zanaflex alabama psilocybin mexican steroids sertraline hydrochloride child overdose lisinopril what is oxycontin purchase tetracycline without prescriptiontiazac coreg tamsulosin hcl lanoxin digoxin thiamin mononitrate fioricet line purchase viagra online phentermine adipex temovate cream snorting flexeril propranolol side effects medicine fluconazole purchase acyclovir online tiazac diltiazem buy ambien overnight rabeprazole drug depression provigil tenuate tablet lexapro and pregnancy bontril diet pills buy eunlose lipitor interaction tadalafil cialis viagra prices increase testosterone buy hydrocodone cod generic tobradex history of anabolic steroids effects of prozac tenuate discount phendimetrazine 35mg flextra pregnancy lortab description smoking klonopin hydrochlorothiazide and pregnancy ultram cash on delivery buying vicodin online yellow xanax bars birth control nordette generic lamisil cheap soma glipizide side effects drug altace retin a wrinkles symmetrel abusesynalar phendimetrazine online paxil pregnancy transderm buy xenical side effects loratadine buy buy adderall without a prescription buy cheap fioricet ghb drug adderall online plavix news lexapro withdrawal symptoms symmetrel buy effexor side effects propranolol anxiety cozaar 50mg serevent law proscar side effects order sibutramine sumatriptan succinat information on tramadol tamiflu no prescription needed cream verapamil prilosec side affects what are steroids children motrin buy generic valium online cheap zyban fosamax warning zocor more drug side effects synalar nasal buy ziaczithromax terazosin drug buy tamiflu mexico rabeprazole sodium ultracet with aspirin triphasil without prescription lipitor prescription side effects valtrex online purchase steroids make ghb furosemide water pillsgemfibrozil esomeprazole magnesium in mexico mircette online cialis levitra vardenafil kidney infection macrobid zyban no prescription active ingredients in adipex fioricet prescription hives motrin allergy paxil quitting medrol side effects clonazepam cod medrol for dogs compazine drug tretinoin mexico athletes and steroids cheapest meridia xenical diet pill nizoral shampoo fosamax patent expiration what is norvasc vermox buy levaquin tablet phencyclidine impurities serevent buyseroquel propoxyphene darvocet order fioricet online buy ativan with overnight delivery effects of lipitor free singulair medicine nexium prescription hydrocodone side effects buy acyclovir hyzaar buy what is triamterene diclofenac 75mg soma online augmentin side effects buy zovirax buspar paxil ionamin phentermine macrobid pregnancy wellbutrin no prescription ultram online pharmacy intravenous pantoprazole guidelines buy mdma acyclovir dosage drug test vicodin atrovent nortriptyline for chronic pain avandia dosage pravachol side effects order vermox online protonix more drug interactions flonase during pregnancy aldactone withdrawal lorazepam alcohol withdrawal generic tamsulosin phenergan vomiting neurontin addiction buy generic propecia picture of valacyclovir levitra 20mg zovirax pills prednisone without a prescription actonel patient reviews minocycline hydrochloride synthroid lawsuittadalafil vicodin drug test protopic side effects biaxin breastfeeding terazosin oral diazepam overnight norco online valporic diltiazem buy norvasc problems diethylpropion 25mg kenalog in orabase diovan generic cialis lawyer columbus levaquin 500mg buy patanol buy flonase online premarin without a prescription lamisil cream buy relenza sumycin buy oxycodone buyoxycontin tramadol abuse adderall and pregnancy orlistat over the counter buy generic viagra temazepam more drug side effects nortriptyline side effects premarin buy online uk kenalog cream generic nexium xanax ambien hydrocodone buy bupropion side effects of tramadol lotrel generic pictures of hydrocodone flumadine prescribing information actonel generic pure mdma marijuana pics lasix oral side effects of sertraline norco bigfoot buy zithromax without prescription lipidos orlistat preven ca capsules buy orlistat furosemide buy side effects of flonase coreg 25mg buy amaryl prozac buy online levitra versus cialis no prescription lorazepam prevacid generic ethinyl estradiol what is spironolactone buy premarin online best price pioglitazone estradiol cream durg flomax viagra for woman information what is propoxyphene meclizine tablets what is premarin suprax cefixime isosorbide side effectspotassium k dur online avandia side effect ambien online without prescription vicodin effects order levitra buy roxicet no prescription needed flextra ds medication cialis tadalafil buy tamsulosin paxil side effects info on miacalcinmicrozide india generic tadalafil evista and breast cancer adipex tenuate paroxetine withdrawal symptoms hydrocodone bitartrate tobradex lawsuit actonel jaw bone buy xalatan on line pharmacy fioricet with codeine folic acid symptoms viagra sales skelaxin generic ultracet pain pill renova cream hydrocodone and pregnancyhyzaar discount xenical alprazolam tablets miacalcin side effects zestril without prescription description of lorazepam ultram oral morphine effects buy alphagan trazodone for sleep sildenafil citrate soft tabs sumatriptan mexico imitrex prilosec online coupon premari