Rails 3包括翻译globalize3 activerecord

时间:2010-12-02 16:09:42

标签: ruby-on-rails activerecord include globalize2

我有这个架构:帖子belongs_to类别和类别has_many帖子。 Post和Category通过gem globalize3进行全球化

class Post < ActiveRecord::Base
  belongs_to :category
  translates :title, :excerpt, :desc # globalize3
end

class Category < ActiveRecord::Base
  has_many :posts
  translates :name # globalize3
end

在我的PostsController中,我获得了这行代码的所有帖子:

def index
  @posts = Post.includes([:translations, {:category => :translations}])
end

问题是我对类别翻译表有n + 1查询问题:

Post Load (0.3ms)  SELECT "posts".* FROM "posts"

Post::Translation Load (0.3ms)  SELECT "post_translations".* FROM "post_translations" WHERE ("post_translations".post_id IN (2,3,4))

# START n+1 query block
Category Load (1.9ms)  SELECT "categories".* FROM "categories" WHERE ("categories"."id" IN (9,12,11))
Category::Translation Load (0.4ms)  SELECT "category_translations".* FROM "category_translations" WHERE ("category_translations".category_id = 9) AND ("category_translations"."locale" IN ('it'))
CACHE (0.0ms)  SELECT "category_translations".* FROM "category_translations" WHERE ("category_translations".category_id = 9) AND ("category_translations"."locale" IN ('it'))
Category::Translation Load (0.2ms)  SELECT "category_translations".* FROM "category_translations" WHERE ("category_translations".category_id = 12) AND ("category_translations"."locale" IN ('it'))
CACHE (0.0ms)  SELECT "category_translations".* FROM "category_translations" WHERE ("category_translations".category_id = 12) AND ("category_translations"."locale" IN ('it'))
Category::Translation Load (0.2ms)  SELECT "category_translations".* FROM "category_translations" WHERE ("category_translations".category_id = 11) AND ("category_translations"."locale" IN ('it'))
CACHE (0.0ms)  SELECT "category_translations".* FROM "category_translations" WHERE ("category_translations".category_id = 11) AND ("category_translations"."locale" IN ('it'))
# END n+1 query block

Category::Translation Load (0.5ms)  SELECT "category_translations".* FROM "category_translations" WHERE ("category_translations".category_id IN (9,12,11))

如何解决这个n + 1查询问题?

2 个答案:

答案 0 :(得分:11)

您应该在模型中启用预先加载的翻译。建议的方法是:

class Category < ActiveRecord::Base
  has_many :posts
  translates :name # globalize3

  default_scope includes(:translations)
end

答案 1 :(得分:2)

Rails 4 :从MichałSzajbe那里得到答案,这仍然可以稍作修改:

public class MainActivity extends FragmentActivity {
private final String TAG = MainActivity.class.getSimpleName();

List<WeakReference<Fragment>> fragList = new ArrayList<WeakReference<Fragment>>();

@Override
protected void onCreate(Bundle savedInstanceState) {
    Log.d(TAG, "onCreate()");
    super.onCreate(savedInstanceState);
    setContentView(R.layout.backbone);
    android.support.v4.app.FragmentManager fm = getSupportFragmentManager();
    android.support.v4.app.Fragment fragment = fm.findFragmentById(R.id.fragmentContainer);

    if (fragment == null) {
        fragment = new Fragment();
        fm.beginTransaction()
                .add(R.id.fragmentContainer, fragment, "SystemDownFragment")
                .addToBackStack(null)
                .commit();
    }
}

public void orderFunc() {
    Log.d(TAG, "orderFunc()");
    if(sendingLogFlag)      attemptSend(TAG + ":orderFunc()");

    for(int i = 0; i < getActiveFragments().size(); i++) {
        getSupportFragmentManager().beginTransaction().remove(getActiveFragments().get(i)).commit();
    }

    Fragment newFragment = new Fragment();
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.add(R.id.fragmentContainer, newFragment, "OrderFragment");
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
    ft.commit();
}

public void checkoutFunc() {
    Log.d(TAG, "checkoutFunc()");
    if(sendingLogFlag)      attemptSend(TAG + ":checkoutFunc()");

    for(int i = 0; i < getActiveFragments().size(); i++) {
        getSupportFragmentManager().beginTransaction().remove(getActiveFragments().get(i)).commit();
    }

    Fragment newFragment = new Fragment();
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.add(R.id.fragmentContainer, newFragment, "CheckOutFragment");
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
    ft.commit();
}

public void reviewFunc(){
    Log.d(TAG, "reviewFunc()");
    if(sendingLogFlag)      attemptSend(TAG + ":reviewFunc()");

    if(getActiveFragments().size() > 1){
        Fragment frag = getSupportFragmentManager().findFragmentByTag("ReviewFragment");
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE);
        ft.remove(frag);
        ft.commit();
    }
    else {
        Fragment newFragment = new Fragment();
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        ft.add(R.id.fragmentContainer, newFragment, "ReviewFragment");
        ft.commit();
    }
    getSupportFragmentManager().executePendingTransactions();
}

public void payFunc(boolean enabled){
    Log.d(TAG, "payFunc()");
    if(sendingLogFlag)      attemptSend(TAG + ":payFunc()");

    if(!enabled){
        Fragment frag = getSupportFragmentManager().findFragmentByTag("PayFragment");
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE);
        ft.remove(frag);
        ft.commit();
    }
    else {
        Fragment newFragment = new Fragment();
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        ft.add(R.id.fragmentContainer, newFragment, "PayFragment");
        ft.commit();
    }
    getSupportFragmentManager().executePendingTransactions();
}

public void doneFunc() {
    Log.d(TAG, "doneFunc()");

    for(int i = 0; i < getActiveFragments().size(); i++) {
        getSupportFragmentManager().beginTransaction().remove(getActiveFragments().get(i)).commit();
    }

    Fragment newFragment = new Fragment();
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
    ft.add(R.id.fragmentContainer, newFragment, "StartupFragment");
    ft.commit();
}

@Override
public void onAttachFragment (Fragment fragment) {
    fragList.add(new WeakReference(fragment));
}

public List<Fragment> getActiveFragments() {
    ArrayList<Fragment> ret = new ArrayList<Fragment>();
    for(WeakReference<Fragment> ref : fragList) {
        Fragment f = ref.get();
        if(f != null) {
            if(f.isVisible()) {
                ret.add(f);
            }
        }
    }
    return ret;
}

private void updateReceivedData() {
    Fragment frag = getSupportFragmentManager().findFragmentByTag("PayFragment");
                        frag.adjustPriceFunc();
}